Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical difference between a struct with only operator() and a normal function

Tags:

c++

c++11

c++14

I have seen code that looks like this:

struct foo_functor {
  template <typename T, typename U>
  constexpr auto operator()(T t, U u) const -> decltype(t | u) {
    return t | u;
  }
};

constexpr foo_functor foo;

As far as I can tell, it's the same as the following:

template <typename T, typename U>
constexpr auto foo(T t, U u) -> decltype(t | u) {
  return t | u;
}

Why would you want to do the first one? Are there any differences? As far as I could see from the compiler output, at least with constexpr, there wasn't. What about if they weren't constexpr, would there be any differences in that case?

Edit: As a note, code very similar to the first example was seemingly being used in place of normal functions. 6 different structures, all with only operator() templates, all were instantiated like the last line of the example. Each was then used exactly like a normal function.

like image 478
evanacox Avatar asked May 29 '20 20:05

evanacox


People also ask

What is the difference between operator function and normal function?

What is the difference between operator functions and normal functions? Operator functions are the same as normal functions. The only difference is, the name of an operator function is always operator keyword followed by the symbol of operator and operator functions are called when the corresponding operator is used.

What are the differences between a C++ struct and AC struct?

A C# struct is managed code, which will be freed by the C# garbage when nobody refers to it anymore. Its destructor is called whenever the garbage collector decides to clean it up. A C++ struct is an unmanaged object, which you have to clean up yourself.

Can a struct contain a function?

Yes, there is a clear answer: C++ struct can have member functions.

Is struct faster than Class C++?

To answer your question, struct is slightly faster.

What is the difference between a struct and a class?

A Structure is not secure and cannot hide its implementation details from the end user while a class is secure and can hide its programming and designing details. Following are the points that expound on this difference: 1) Members of a class are private by default and members of a struct are public by default.

Can there be null values in any structure member?

There can be no null values in any structure member. It is a reference type data type. It is a value type data type. It is declared using the class keyword. It is declared using the struct keyword. Inheritance is possible in class. Inheritance is not possible in structures.

What is the difference between structure variable and structure class?

Instance of 'structure' is called 'structure variable'. Instance of a 'class' is called 'object'. Supports polymorphism and a class can also be inherited. A structure is a collection of variables of dissimilar data types, all referenced by one name. A structure declaration forms a template that is used to create an instance of the structure.

What are the similarities between structure and class in C++?

Similarities 1 In C++, both the structure and class are syntactically equivalent. 2 Both structure and class can declare some of their members private. 3 The name of a structure or class can be used as a stand-alone type. 4 Both structure and class support the mechanism of inheritance.


1 Answers

Someone suggested in the comments that a function object can have additional state. While this is true, I would be a bit more specific: you can create multiple copies of a function object with varying state. If the function object is singleton, then this point is moot; a function can also have state in the form of global variables.

And if your function object is declared constexpr, then none of its internal state can be mutable. This puts it in the same position as a constexpr function: calling it can be a constant expression but only as long as it doesn't access any non-constant-expression global state.

One important difference before C++17 is that functions could be inline, whereas objects could not be. In C++14, if you defined the functor foo in a header, then there would be one copy of it per translation unit. If you needed foo to have the same address in all translation units, you would need to declare it as an inline function. But in C++17, function objects can be inline too.

But even if you only have a single instance of the function object, and it has no state, and you are using C++17 or later, there is still at least one important difference between that and a function: functions can be found by argument-dependent lookup, whereas function objects cannot. This is the reason why some "functions" in the C++20 Ranges library actually cannot be functions at all, and must be function objects. These are informally referred to as niebloids.

like image 86
Brian Bi Avatar answered Oct 23 '22 04:10

Brian Bi