Reputation: 1346
In node.js I can write lambda inside lambda and capture whichever variable I want. But in C++11, as lambda functions are actually functor object, variable capturing is not so easy with nested lambdas.
I'm using [this]
to capture this pointer so I can use class members. But inside a lambda, this
pointer points to the lambda instead of the outter class.
void MyClass::myFunction() {
// call the lambda1
connect(action, trigger, [this]() {
// in the lambda1, call lambda2
sendCommand([this]() { // <-- I want `this` point to the outter class
this->myMember.log("something"); // myMember is the member of class MyClass
});
});
}
I know it can be done by rename this to another pointer variable and capture that variable instead of this
, but I think that way is ugly.
Is there any better way to capture outter this
?
Upvotes: 2
Views: 14541
Reputation: 42554
But inside a lambda,
this
pointer points to the lambda instead of the outter class.
No, inside the lambda this
has the same value as outside. The only problem in your code is accessing this
with .
instead of ->
. This program:
void MyClass::myFunction() {
std::cout << this << std::endl;
// call the lambda1
connect(action, trigger, [this]() {
std::cout << this << std::endl;
// in the lambda1, call lambda2
sendCommand([this]() { // <-- I want `this` point to the outter class
std::cout << this << std::endl;
this->myMember.log("something"); // myMember is the member of class MyClass
});
});
}
Prints the same value for this in all three places:
g++ -std=c++11 -O3 -Wall -Wextra -pedantic -pthread main.cpp && ./a.out 0x7fff4286c80f 0x7fff4286c80f 0x7fff4286c80f
N3936 (C++14 Working Draft) [expr.prim.lambda]/18 states:
Every id-expression within the compound-statement of a lambda-expression that is an odr-use (3.2) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [ Note: An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. Furthermore, such an id-expression does not cause the implicit capture of the entity. —end note ] If
this
is captured, each odr-use ofthis
is transformed into an access to the corresponding unnamed data member of the closure type, cast (5.4) to the type ofthis
. [ Note: The cast ensures that the transformed expression is a prvalue. —end note ]
Upvotes: 3
Reputation: 11736
You simply capture outer lambda's context:
#include <iostream>
struct Omg
{
int lol= 42;
Omg()
{
[this]{ [&]{ std::cout<< this-> lol; }(); }();
}
};
int main(){ Omg(); }
Upvotes: 3