What are the differences between these 4 lambda expressions?

  • A+
Category:Languages

I know this could seem very stupid for non-noob C++ developers, but what are the differences between these 4 lambda expressions? Code:

#include <iostream> #include <math.h> #include <functional>  inline double MyFunction(double a, double b, double c) {     return (a + b + c); }  inline void FunctionWrapper(std::function<double(double)> tempFunct, double value) {     std::function<double(double)> funct;      funct = tempFunct;      std::cout << "result: " << funct(value) << std::endl; }  int main() {         double value = 100.0;      FunctionWrapper([](double value) { return MyFunction(value, 1.0, 2.0); }, value);     FunctionWrapper([](double value) -> double { return MyFunction(value, 1.0, 2.0); }, value);      FunctionWrapper([value](double value) { return MyFunction(value, 1.0, 2.0); }, value);     FunctionWrapper([value](double value) -> double { return MyFunction(value, 1.0, 2.0); }, value); } 

It seems it does the same? Either using two different "notations" and using the value as closure?

 


In this context, they all produce the same results. However, there are logical differences between them.

  • [](double value) { return MyFunction(value, 1.0, 2.0); }

    This is a lambda which takes a single parameter of type value and passes this into MyFunction. Its return type is deduced from the return statement to be that of MyFunction, which is double.

  • [](double value) -> double { return MyFunction(value, 1.0, 2.0); }

    This is the same lambda as before, but this time its return type is explicitly specified to be double. It's the same in this case, but it would be different from the first one if the return type of MyFunction was something else. In that case, the first one would return what MyFunction returns, while this one would still return double.

  • [value](double value) { return MyFunction(value, 1.0, 2.0); }

    This one depends on the standard version used. In C++11 and 14, this one captures main's local variable value. However, that capture is hidden by the lambda's parameter value, so it's effectively useless. It would be different if the lambda had been declared as e.g. [value](double v) { return MyFunction(value, 1.0, 2.0); }. This would have passed on the captured value, and not its parameter.

    In C++17 and above, this was changed and it's actually ill-formed (compilation error). Naming a lambda parameter the same as something you capture is no longer allowed.

    Since the change was a defect report (CWG 2211), it applies retroactively and so it's legal for compilers to reject such code even in earlier C++ versions.

  • [value](double value) -> double { return MyFunction(value, 1.0, 2.0); }

    Same as lambda number 3, with explicit return type specification (the difference between 3 and 4 is exactly the same as between 1 and 2).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: