c++ c++11 gcc language-lawyer

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.