Search code examples
c++lambdafunction-object

Is it wise to prefer lambdas to function objects?


After some searching and testing, I have learned the following facts about lambda expression. 1) when we write a lambda expression, the compiler would create an anonymous function object for it, and make it as an instance of the function object; 2) the captured variables of a lambda expression will be used to initialize the member data of the created function object; 3) when we store a lambda function, we actually get a named instance of the function object; 4) a generic lambda function is actually a function object template; 5) a stored (plain and even generic) lambda expression can be declared and defined with template; and 6) a stored lambda expression template can even be partially specialized, just as function objects.

Given all the features of lambdas stated above, it seems to me that, through lambdas, we are able to do whatever we used to do with function objects, and regarding efficiency, they should have same performance.

On the other hand, lambdas also have additional advantages: 1) a lambda expression is more understandable than a function object, especially for inline, short functions; and 2) defining a stored lambda can be seen as a kind of syntactic sugar for defining a function object, and making an instance of it.

Therefore, for me, it seems that we have no reasons to define a function object manually any more.

Of course, I also have some concern for substituting lambdas for function objects universally, like 1) for functions more than, say, 10 lines, defining them as a stored lambda may be unusual (or even awkward, I don't know), and 2) defining lambdas at file-level may (or may not, I am not quite sure) cause some unexpected problems.

Here are my questions: is it wise to prefer lambdas to function objects? Is there any other advantages that a function object have but lambdas not? Is my concern reasonable? And, is there any other concern that I should notice when using lambdas instead of FO universally?

Thanks for any reply!


Solution

  • Lambdas are a terse syntax for certain kinds of function objects.

    They cannot be trivially constructed, they can have exactly one (possibly template) operator(), and their type cannot be named without first having access to an instance and using decltype.

    As of C++14, they are not constexpr friendly, and they are not guaranteed to be trivially copyable even if their state should be.

    Two lambdas with the same capture types and method do not share a type unless declared at the same spot; this can cause symbol bloat.

    You cannot declare other operations in a lambda besides (), like friend bool operator< or ==, or whatever.

    Given these restructions, sure, use lambdas. Terseness has lots of utility.