简体   繁体   中英

C++11 variable capture with lambda inside another lambda

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 ?

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 of this is transformed into an access to the corresponding unnamed data member of the closure type, cast (5.4) to the type of this . [ Note: The cast ensures that the transformed expression is a prvalue. end note ]

You simply capture outer lambda's context:

#include <iostream>

struct Omg
{
  int lol= 42;

  Omg()
  {
    [this]{ [&]{ std::cout<< this-> lol; }(); }();
  }
};

int main(){ Omg(); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM