# 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).