c++ - Fallo de segmentación para la función lambda en el inicializador de miembro de datos no estáticos
c++11 gcc (2)
No estoy seguro de un posible error de GCC en la inicialización de una std::function
desde una función lambda que captura this
en un inicializador de miembro de datos no estáticos. ¿Está permitido por el estándar de C ++ o es este UB?
Dado el siguiente código:
#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";
}
En mi entendimiento, debería imprimir 1
. Sin embargo, cuando se construye con GCC 5.4.0 o GCC 6.2.0, af(1)
emite un fallo de segmentación, porque el puntero capturado es nulo.
Las siguientes alternativas funcionan como esperaba:
Usando la lista de inicializadores de constructor:
template <typename T> struct B { B() : f([this](T v) { x = v; }) {} T x = 0; std::function<void(T)> f; };
Sin plantilla:
struct C { int x = 0; std::function<void(int)> f = [this](int v) { x = v; }; };
Además, cuando se construyó con Clang 3.8.0, las tres versiones se comportan como espero, lo que no significa que no sea UB.
Su código compila y se ejecuta en VS2015 (Windows). Así que este es probablemente un error del compilador.
Además, si elimina la plantilla, funciona en http://cpp.sh/ Intente este código:
#include <functional>
#include <iostream>
struct A {
int x = 0;
std::function<void(int)> f = [this](int v) { x = v; };
};
int main() {
A a;
a.f(1);
std::cout << a.x << "/n";
}
ejecutando el código original en cpp.sh da:
internal compiler error: in tsubst_copy, at cp/pt.c:12569
Please submit a full bug report
Así que supongo que es un error.
Tú no puedes hacer:
template <typename T>
struct A {
T x = 0;
std::function<void(T)> f = [this](T v) { x = v; };
};
Como this
no existe cuando se define f
. Necesita iniciar f
en un constructor, como:
A(){ f = [this](T v){ x=v; } }
Funcionó con G ++ 4.8.