【问题标题】:C++11 lambda capture `this` and capture local variables by valueC ++ 11 lambda捕获`this`并按值捕获局部变量
【发布时间】:2018-05-04 21:39:06
【问题描述】:

下面的 lambda 函数捕获 this(因此 bar() 可以访问其实例变量)和局部变量 a,b,c

class Foo {
  int x, y, z;
  std::function<void(void)> _func;
  // ...
  void bar() {
     int a,b,c;
     // ...
     _func = [this,a,b,c]() { // lambda func
        int u = this->x + a;
        // ...
     };
  }
};

但如果我想捕获许多实例变量并希望避免在捕获列表中明确命名它们,我确实 似乎能够做到这一点:

     _func = [this,=]() { // lambda func
        // ...
     };

我在= 后面的this, 处收到编译器错误:

  error: expected variable name or 'this' in lambda capture list 

如果我试试这个

     _func = [=,this]() { // lambda func
        // ...
     };

我明白了

  error: 'this' cannot be explicitly captured when the capture default is '='

是否有按值捕获this 和其他所有内容的简写?

更新: [=, this] 作为 lambda 捕获是 new feature of C++20

【问题讨论】:

  • [=] 也不能捕获this 吗?
  • 真的吗?天哪,它确实如此。我想我会删除我的问题。
  • 我想 SO 希望我把这个问题留在这里......也许其他一些糟糕的编程灵魂(例如,曾经使用 [unowned self] 的 Swift 程序员)会发现它很有用。
  • [this,=] 将是一个令人困惑的矛盾修饰法,因为这是一个指向对象的指针..所以实际上您将通过引用捕获整个对象,这与值 [=] 的默认值冲突。

标签: c++ c++11 lambda


【解决方案1】:

正如 cppreference 所说:

[=] 通过复制捕获 lambda 主体中使用的所有自动变量,并通过引用捕获当前对象(如果存在)

【讨论】:

【解决方案2】:

[*this,=] 通过 中的值捕获两个局部变量对象。

[&amp;] 通过引用捕获局部变量,*this 通过引用或this(指针)通过值。

两种默认捕获模式都以相同的方式捕获this。只有在 中才能更改。

【讨论】:

    【解决方案3】:

    [=] 已经按值捕获了this。看看下面的代码:http://cpp.sh/87iw6

    #include <iostream>
    #include <string>
    
    struct A {
        std::string text;
    
        auto printer() {
            return [=]() {
                std::cout << this->text << "\n";
            };
        }
    };
    
    int main() {
        A a;
        auto printer = a.printer();
        a.text = "Hello, world!";
    
        printer();
    }
    

    【讨论】:

    • this 是当前对象,是通过引用捕获的,不是吗?
    • this 是指向当前对象的指针,通过引用捕获。捕获this 指针实际上是通过引用捕获对象。
    • 是的,这就是为什么我发现您的说法“......已经通过价值捕捉到了这一点”具有误导性。
    • 我不知道,因为this 是一个指针,这就是按值复制指针的工作原理。
    【解决方案4】:

    [=] 将起作用,因为它通过复制捕获了 lambda 主体中使用的所有自动变量。

    这是示例输出:https://www.ideone.com/kkXvJT

    #include <iostream>
    #include <functional>
    
    class Foo
    {
      int x, y, z;
      std::function<void(void)> _func;
    
    public:
      Foo(int a): x(a), y(0), z(0)  {}
    
      void bar()
      {
        int a = 1,b,c;
        _func = [=]()
        {
          int u = this->x + a;
          std::cout << u << std::endl;
        };
    
        _func(); // lambda call
      }
    };
    
    int main()
    {
      Foo obj(1);
      obj.bar();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2017-08-14
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多