【问题标题】:How to capture a variable of this object in lambda?如何在 lambda 中捕获此对象的变量?
【发布时间】:2019-05-23 07:23:29
【问题描述】:

我在 SO 上看到了很多关于通过引用捕获 this 的答案,但我有一个不同的问题。如果我想捕获 this 对象拥有的特定变量怎么办?

例如:

auto rel_pose = [this->_last_pose["main_pose"],&pose](Eigen::VectorXd pose1, Eigen::VectorXd pose2)
    {
        // Some code
        return pose;
    };

我想按值捕获this 的特定变量,并在我的 lambda 表达式中使用它。为什么这是不可能的?

【问题讨论】:

    标签: c++ lambda c++14


    【解决方案1】:

    您可以应用 by-copy capture with an initializer(C++14 起)(或使用初始化程序的按引用捕获,取决于您的需求),例如

    auto rel_pose = [some_pose = this->_last_pose["main_pose"], &pose](Eigen::VectorXd pose1, Eigen::VectorXd pose2)
    {
        // Some code using some_pose
        return pose;
    };
    

    请注意,我们只能在 lambda 中使用 capture 标识符,我们不能直接捕获像 this->_last_pose["main_pose"] 这样的表达式。 带有初始化器的捕获只是直接解决了这些问题。

    【讨论】:

    • 为什么我们需要复制对象的变量才能捕获它?只是一个 C++ 规则?
    • @Edmund 我们不需要复制它。我们可以使用引用。
    • @Edmund ???你说“想通过值来捕获this的具体变量”..你也可以通过引用来捕获。
    • @songyuanyao 我的意思是赋值操作,在捕获括号里代表什么?
    • @Edmund 所以每当我们想在 lambda 中传递某个对象的变量时,我们都需要为此初始化一个新变量 替代方案如何工作?您在示例中指定的不仅仅是“对象的变量”,它是一个涉及对象的完整表达式。您不能只是将它放在捕获中,并以某种方式期望 lambda 的主体在 lambda 主体中找到相同的任意表达式时识别,并自动将其转换为捕获的引用。尤其是当任意表达式可能以微妙的方式有所不同时。
    【解决方案2】:

    有可能:

    struct S
    {
        int i = 7;
        char c = 0;
    };
    
    int main(int argc, char* argv[])
    {
        S s;
        auto l = [integer = s.i]() {
            return integer;
        };
    
        return l();
    }
    

    【讨论】:

    • 为什么我们需要复制对象的变量才能捕获它?只是一个 C++ 规则?
    【解决方案3】:

    为什么这是不可能的?

    这是可能的,就像其他答案所示。但是您必须明确地这样做。访问 lambda 中当前对象的任何成员都会自动转换为通过 this 指针进行的访问。当你写一个普通的[this->_last_pose["main_pose"],&pose]时,真正捕获的是this,而对_last_pose的访问是通过它。

    这就是为成员变量指定 lambda 捕获的简单方法。感谢您正在编译 C++14。在 C++11 中,按值捕获成员并不像添加一个执行副本的 init 捕获那么容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      相关资源
      最近更新 更多