我正在尝试创建类似于std::tuple
的东西,这是一种使用可变参数模板和递归继承的编译时列表,如下面的实现所示。
我的问题是,尽管以下所示的实现在msvc上运行良好,但clang和icc ConstExprList::Get
在gcc(trunk版本)上始终返回0。
如果在启用-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>();
}
答案 0 :(得分:4)
该警告具有误导性,但指出了一个实际问题。 m_head
是初始化为临时文件的引用。这不是会导致临时生存期延长的环境之一,因此您的引用会悬空。