Consider this:
#include <iostream>
#include <functional>
std::function<void()> task;
int x = 42;
struct Foo
{
int& x;
void bar()
{
task = [=]() { std::cout << x << '\n'; };
}
};
int main()
{
{
Foo f{x};
f.bar();
}
task();
}
My instinct was that, as the actual referent still exists when the task is executed, we get a newly-bound reference at the time the lambda is encountered and everything is fine.
However, on my GCC 4.8.5 (CentOS 7), I'm seeing some behaviour (in a more complex program) that suggests this is instead UB because f
, and the reference f.x
itself, have died. Is that right?
To capture a member reference you need to utilize the following syntax (introduced in C++14):
struct Foo
{
int & m_x;
void bar()
{
task = [&l_x = this->m_x]() { std::cout << l_x << '\n'; };
}
};
this way l_x
is an int &
stored in closure and referring to the same int
value m_x
was referring and is not affected by the Foo
going out of scope.
In C++11 we can workaround this feature being missing by value-capturing a pointer instead:
struct Foo
{
int & m_x;
void bar()
{
int * p_x = &m_x;
task = [=]() { std::cout << *p_x << '\n'; };
}
};
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