Подтвердить что ты не робот

Ошибка сегментации для лямбда-функции в инициализаторе нестатических данных

Я не уверен в возможной ошибке GCC при инициализации std::function из функции лямбда-захвата this в инициализаторе нестатических данных. Разрешено ли это стандартом С++ или это UB?

С учетом следующего кода:

#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";
}

В моем понимании, он должен печатать 1. Однако при построении с помощью GCC 5.4.0 или GCC 6.2.0 a.f(1) испускает ошибку сегментации, потому что захваченный указатель this имеет значение null.

Следующие альтернативы работают так, как я ожидал:

  • Использование списка инициализаторов конструктора:

    template <typename T>
    struct B {
        B() : f([this](T v) { x = v; }) {}
        T x = 0;
        std::function<void(T)> f;
    };
    
  • Без шаблона:

    struct C {
        int x = 0;
        std::function<void(int)> f = [this](int v) { x = v; };
    };
    

Кроме того, при построении с Clang 3.8.0 все три версии ведут себя так, как я ожидаю, что не означает, что это не UB.

4b9b3361

Ответ 1

Вы не можете:

template <typename T>
struct A {
    T x = 0;
    std::function<void(T)> f = [this](T v) { x = v; };
};

Поскольку this не существует, когда вы определяете f. Вам нужно инициализировать f в конструкторе, например:

A(){ f = [this](T v){ x=v; } }

Он работал с g++ 4.8.

Ответ 2

Ваш код компилируется и запускается на VS2015 (windows). Таким образом, это, вероятно, ошибка компилятора.

Кроме того, если вы удалите шаблон, он будет работать на http://cpp.sh/ Попробуйте этот код:

#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";
}

запуск исходного кода на cpp.sh дает:

 internal compiler error: in tsubst_copy, at cp/pt.c:12569
Please submit a full bug report

Итак, я думаю, что это ошибка