Is there ever a situation where it makes more sense to create a functor than to use a lambda?
I know my question is effectively the reverse of when to use a lambda over a functor, but I can't think of a situation in practice where a functor would be preferred over a lambda. Any thoughts on this?
The functor is general, and adds whatever you initialized it with), and they are also potentially more efficient. In the above example, the compiler knows exactly which function std::transform should call. It should call add_x::operator() . That means it can inline that function call.
50: Use a lambda when a function won't do (to capture local variables, or to write a local function) The difference in the usage of functions and lambda functions boils down to two points. You can not overload lambdas. A lambda function can capture local variables.
std::function<int(int,int)>; std::function<void(double)> ... Functors allow to write functional programs in C++. Lambdas are syntactic sugar to simplify this. With functors/lambdas classic patters from functional programming (e.g. map / filter /reduce) can be applied in C++.
A lambda is a functor - just defined with a shorter syntax.
The problem is that this syntax is limited. It doesn't always allow you to solve a problem in the most efficient and flexible way - or at all. Until C++14, the operator()
couldn't even be a template.
Furthermore, a lambda has exactly one operator()
. You can't provide several overloads to distinguish between, say, the types of the arguments:
struct MyComparator { bool operator()( int a, int b ) const {return a < b;} bool operator()( float a, float b ) const {return /*Some maths here*/;} };
.. or value category of the object argument (that is, the closure object that is called). You can also not define special member functions, including constructors and destructors - what if a functor shall be responsible for resources?
Another problem with lambdas is that they cannot be recursive. Of course, normal functions (including operator functions) can be.
Also consider that lambdas are unhandy to use as comparators for associative containers or deleters for smart pointers: You can't directly pass the closure type as a template argument and need to construct the containers member from another closure object. (Closure types don't have a default constructor!). For a block-scope map
that isn't too much of a hassle:
auto l = [val] (int a, int b) {return val*a < b;}; std::map<int, int, decltype(l)> map(l);
Now, what happens if your map
is a data member? What template argument, what initializer in the constructors initialization list? You'd have to use another static data member - but since you have to define it outside the classes definition that is arguably ugly.
To sum up: Lambdas aren't useful for more complex scenarios because they weren't made for them. They provide a short and concise way of creating simple function objects for correspondingly simple situations.
I would consider using a functor over a lambda when I
I could think of two cases:
When functor carries internal state, thus there is a non-trivial life time issue with the functor. It keeps "something" between the uses
When you have to use same code all over the place, writing and keeping it as a functor in its own header might be a good idea from maintenance point-of-view
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With