Consider the following code:
int main() {
int n = 0;
return [n] { return n; }(); // ok
}
According to https://cppinsights.io, the code above will be translated into the following code:
int main() {
int n = 0;
class __lambda_3_12 {
public:
inline /*constexpr */ int operator()() const {
return n;
}
private:
int n;
public:
__lambda_3_12(int& _n) : n{_n} {
}
} __lambda_3_12{n};
return __lambda_3_12.operator()();
}
However, the following code is ill-formed:
int main() {
int n = 0;
// error: invalid use of 'this' outside of a non-static member function
return [n] { return this->n; }();
}
I think the C++ standard must have forbidden the compiler to use this
pointer to access the captured variables. However, I cannot find the exact statements in 7.5.6 [expr.prim.lambda] of the C++ standard draft.
Below are the relevant sections from the latest C++ standard (emphasis mine):
7.5.6.2/p1&p2 [expr.prim.lambda.closure]
The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.
7.5.6.2/p15 [expr.prim.lambda.closure]
- The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but it is not within the scope of the closure type.
[Example 10:
struct S1 { int x, y; int operator()(int); void f() { [=]()->int { // equivalent to S1::operator()(this->x + (*this).y) // this has type S1* return operator()(this->x + y); }; } };
end example]
Note that the standard explicitly states:
The lambda-expression's compound-statement yields the function-body of the function call operator, but it is not within the scope of the closure type.
So, the statements in the lambda expression, which are not within the closure type's scope, cannot access the this
pointer of the closure object.