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
Capture clause A lambda can introduce new variables in its body (in C++14), and it can also access, or capture, variables from the surrounding scope. A lambda begins with the capture clause. It specifies which variables are captured, and whether the capture is by value or by reference.
Lambdas always capture objects, and they can do so by value or by reference.
Local variables from outer scope can be captured inside Lambda in 2 modes i.e.
Much like functions can change the value of arguments passed by reference, we can also capture variables by reference to allow our lambda to affect the value of the argument. To capture a variable by reference, we prepend an ampersand ( & ) to the variable name in the capture.
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 c++17.
[&]
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 c++17 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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With