Переменная Constexpr появляется неинициализированной внутри лямбды - PullRequest
2 голосов
/ 28 января 2012

В приведенном ниже примере кода я ожидаю, что результат будет следующим, поскольку x является static constexpr переменной.

5
5
5
5

Однако g ++ предупреждает меня, что x неинициализируется внутри лямбда-функции, когда я компилирую с -Wall, и последние три строки выходных данных меняются, предположительно, потому что печатается значение неинициализированной памяти в стеке. Вот один из возможных выводов программы, когда она компилируется с параметрами -Wall -std=c++0x. Почему результат не соответствует ожиданиям?

5
32718
32718
32718

Если это поможет, ожидаемый вывод создается, когда constexpr удаляется в объявлении constexpr T x.

Пример программы

#include <algorithm>
#include <iostream>

struct _foo
{
        template <class T>
        struct traits
        {
                static constexpr T val = 5;
        };

        template <class T>
        constexpr T getval() const { return traits<T>::val; }
} foo;

struct _test
{
        template <class T>
        void bar(const T& t)
        {
                int arr[] = { 1, 2, 3 };
                constexpr T x = foo.getval<T>();
                std::cout << x << std::endl;
                std::for_each(arr, arr + 3, [&](int i) {
                        std::cout << x << std::endl;
                });
        }
} test;

int main()
{
        test.bar(5u);
        return 0;
}

Ответы [ 2 ]

2 голосов
/ 15 февраля 2012

Это действительно была ошибка компилятора. Я сообщил об этом здесь , и это было подтверждено некоторое время назад. Это не приводит к сбою на старых версиях g ++, потому что ключевое слово constexpr просто анализируется и игнорируется.

0 голосов
/ 28 января 2012

Вы должны захватить x в списке захвата лямбды:

std::for_each(arr, arr + 3, [&](int i) { // notice the & (capture the outside env
                                         // by reference
    std::cout << x << std::endl;
});
...