Reputation: 39881
Is it correct to write such code:
class A
{
private:
int m_int;
public:
void foo()
{
int a = 1;
int b = 2;
int c = 3;
float f = 3.14f;
std::string s("Something");
const auto f1 = [=] ()
{
// use only a, b, c
int d = a + b + c;
const auto f2 = [=]
{
// use f, s and also d
std::cout << f << s << d ;
}
};
}
};
The problem is inner lambda uses some variables that outer one does not require. If this is not valid, then how I should write?
NOTE: I could also capture pointer variables. So a
, b
, c
, f
, and s
could be pointers too.
Upvotes: 1
Views: 151
Reputation: 311068
According to the C++ Standard (5.1.2 Lambda expressions)
9 A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression; any other lambda-expression shall not have a capture-default or simple-capture in its lambda-introducer. The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the innermost enclosing function and its parameters. [ Note: This reaching scope includes any intervening lambda-expressions. —end note ]
So the reaching scope of the second lambda is the scope of the member function foo()
. As the lambda expression has default capture then it can capture local variables in this reaching scope.
It is important also to pay attention to the following part of paragraph #13 of the same section
13 ... If a lambda-expression captures an entity and that entity is not defined or captured in the immediately enclosing lambda expression or function, the program is ill-formed.
In your example the enclosing lambda captures implicitly all required variables for the inner lambda from the function block scope using the default capture.
Upvotes: 2
Reputation: 913
This will work because you are capturing all local variables by value by typing [=]. So f, s and d will be visible inside f2, but it would be only the copies, not the actual variables
Upvotes: 0
Reputation: 26506
Quoting from http://en.cppreference.com/w/cpp/language/lambda
[=] captures all automatic variables odr-used in the body of the lambda by value
Because you capture all the variables of foo
in f1
, there is not problem using them in f2
.
so it is valid, although you might want to consider catching them by refernece.
Upvotes: 0
Reputation: 62603
The code in question as asked (notwithstanding typo in inner lambda declaration) is correct. Since the first lambda is going to capture everything from the enclosing function, the second lambda is going to have access to it through 'capture all' of the enclosing lambda.
Upvotes: 4