I am unsure about a possible GCC bug in initialization of a std::function
from a lambda function capturing this
in a non-static data member initializer. Is this allowed by the C++ standard or is this UB?
Given the following code:
#include <functional>
#include <iostream>
template <typename T>
struct A {
T x = 0;
std::function<void(T)> f = [this](T v) { x = v; };
};
int main() {
A<int> a;
a.f(1);
std::cout << a.x << "\n";
}
In my understanding, it should print 1
. However, when built with GCC 5.4.0 or GCC 6.2.0, a.f(1)
emits a segmentation fault, because the captured this
pointer is null.
The following alternatives work as I expected:
Using constructor initializer list:
template <typename T>
struct B {
B() : f([this](T v) { x = v; }) {}
T x = 0;
std::function<void(T)> f;
};
Without template:
struct C {
int x = 0;
std::function<void(int)> f = [this](int v) { x = v; };
};
Also, when built with Clang 3.8.0, all three versions behave as I expect, which doesn't mean it is not UB.
You cannot do:
template <typename T>
struct A {
T x = 0;
std::function<void(T)> f = [this](T v) { x = v; };
};
As this
does not exist when you define f
. You need to initilize f
in a constructor, such as:
A(){ f = [this](T v){ x=v; } }
It worked with G++4.8.
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