简体   繁体   中英

C++11 lambda capture `this` and capture local variables by value

The lambda function below captures this (so bar() can access its instance vars) and the local variables 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;
        // ...
     };
  }
};

But if I want to capture many instance variables and wish to avoid explicitly naming them in the capture list, I do not seem to be able to do this:

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

I get a compiler error at the = following this, :

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

If I try this

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

I get

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

Is there a shorthand for capturing this and everything else by value?

UPDATE: [=, this] as a lambda capture is a new feature of C++20

As cppreference says:

[=] captures all automatic variables used in the body of the lambda by copy and current object by reference if exists

[=] does what you want -- it captures anything not a member variable by value, and *this by reference (or this by value).

[*this,=] captures both local variables and the object by value in .

[&] captures local variables by reference and *this by reference or this (the pointer) by value.

Both default capture modes capture this the same way. Only in can you change that.

[=] already captures this by value. Take a look at the following code live here: 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();
}

[=] will work, because it captures all automatic variables used in the body of the lambda by copy.

Here is the example output: 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();
}

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