【问题标题】:C++11 variable capture with lambda inside another lambda在另一个 lambda 中使用 lambda 捕获 C++11 变量
【发布时间】:2014-06-24 13:58:18
【问题描述】:

在 node.js 中,我可以在 lambda 中编写 lambda 并捕获我想要的任何变量。但在 C++11 中,由于 lambda 函数实际上是函子对象,因此使用嵌套的 lambda 捕获变量并不那么容易。

我正在使用[this] 来捕获此指针,以便我可以使用类成员。但在 lambda 内部,this 指针指向 lambda 而不是外部类。

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
        });
    });
}

我知道可以通过将其重命名为另一个指针变量并捕获该变量而不是 this 来完成,但我认为这种方式很难看。

有没有更好的方法来捕捉外部this

【问题讨论】:

  • @BЈовић 为什么通过复制隐式捕获this 比通过复制显式捕获它“更好”?
  • @Casey 我的错。我的意思是[&amp;]
  • @BЈовић 通过引用捕获this 是没有意义的,因为它是prvalue。事实上,该标准不允许通过引用显式捕获this[&amp;this][=,this] 都被明确禁止。允许通过引用隐式捕获this 可能是标准中的错误。编译器将隐式引用捕获视为按副本捕获。 (更多讨论请参见restriction about default capture mode and 'this' in C++ lambda-expression。)

标签: c++ c++11 lambda


【解决方案1】:

但在 lambda 内部,this 指针指向 lambda 而不是外部类。

不,在 lambda this 内部与外部具有相同的值。您的代码中唯一的问题是使用. 而不是-&gt; 访问this。这个程序:

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 工作草案)[expr.prim.lambda]/18 状态:

lambda-expressioncompound-statement 中的每个 id-expression 都是实体的 odr-use (3.2)被复制捕获的转换为对闭包类型的相应未命名数据成员的访问。 [ 注意: 不是 odr-use 的 id-expression 指的是原始实体,而不是闭包类型的成员。此外,这样的 id-expression 不会导致实体的隐式捕获。 —尾注] 如果this 被捕获,this 的每个 odr-use 都将转换为对闭包类型的相应未命名数据成员的访问,将 (5.4) 类型转换为this。 [ 注意: 强制转换确保转换后的表达式是纯右值。 —尾注 ]

【讨论】:

  • 对不起,我在上面的代码中犯了一个错误(我已经修复了,现在是this-&gt;而不是this.)。
  • 我试过你的方法但失败了。我打印出this 的两个不同值:ffffe190 和 ffffba53。我在 Qt 中这样做并使用 std::function 作为回调类型。
  • @songziming 听起来像一个编译器错误。 Are you by any chance using VS2010?
【解决方案2】:

您只需捕获外部 lambda 的上下文:

#include <iostream>

struct Omg
{
  int lol= 42;

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

int main(){ Omg(); }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多