GCC аноним не инициализирован - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь создать что-то похожее на std::tuple, своего рода список времени компиляции, использующий шаблоны с переменным числом аргументов и рекурсивное наследование, как показано в приведенной ниже реализации.

Моя проблема заключается в том, что, хотя реализация, показанная ниже, прекрасно работает на msvc, clang и icc ConstExprList::Get всегда возвращает 0 на gcc (версия магистрали).

Если компилировать код с включенными опциями -Wall -Werror, gcc выдает следующую ошибку:

anonymous is used uninitialized in this function [-Werror=uninitialized].

Обратите внимание, что при отключенной оптимизации ошибка не возникает.

Это ошибка в реализации gcc или я что-то упустил?

#include <type_traits>

template <typename... Args>
class ConstExprList;

template <typename Head, typename... Tail>
class ConstExprList<Head, Tail...> : public ConstExprList<Tail...>
{
public:
    ConstExprList(const Head& head, const Tail&... tail) : ConstExprList<Tail...>(tail...),  m_head(head) {}

    template <std::size_t Idx>
    inline typename std::enable_if<Idx == 0, Head>::type Get(void) const noexcept
    {
        return m_head;
    }

    template <std::size_t Idx>
    inline typename std::enable_if<Idx != 0, Head>::type Get(void) const noexcept
    {
        return ConstExprList<Tail...>::template Get<Idx - 1>();
    }

private:
    const Head& m_head;
};

template <typename Head>
class ConstExprList<Head>
{
public:
    ConstExprList(const Head& head) : m_head(head) {}

    template <std::size_t Idx>
    inline auto Get(void) const noexcept
    {
        static_assert(Idx == 0, "Index out of range");
        return m_head;
    }

private:
    const Head& m_head;
};

int main(void)
{
    ConstExprList<int, int> l(7, 3);

    return l.Get<0>();
}

1 Ответ

0 голосов
/ 03 сентября 2018

Предупреждение вводит в заблуждение, но указывает на реальную проблему. m_head является ссылкой, инициализированной для временного. Это не один из контекстов, который приведет к продлению срока службы временного хранилища, поэтому ваши ссылки остаются висящими.

...