decltype中的可变参数模板包

时间:2013-09-27 07:53:52

标签: c++ c++11 variadic-templates

我可以写为

template< class T0> struct Last0
{  
  using type = decltype(T0{}); // OK compiles. `type = T0`
};


template< class T0, class T1> struct Last1
{
    using type = decltype(T0{}, T1{}); // OK, compiles. `type = T1`
};

template< class T0, class T1, class T2> struct Last3{
   using type = decltype(T0{}, T1{}, T2{}); // Ok, compiles. `type = T2`
};

但是,当我使用可变参数模板时,它没有被编译:

template< class ... T> struct Last{
   using type = decltype(T{} ... ); //<--- Error !!!
};

有什么问题?

2 个答案:

答案 0 :(得分:5)

有一个可以发生包扩展的语言结构的分类列表(C ++11,14.5.3§4)。除了sizeof...之外,它总是在构造中,逗号,是列表的语法分隔符,而不是运算符。表达式不能是包扩展。

要获取包中的最后一个类型,您可以执行以下操作:

template <class Head, class... Tail>
struct Last {
  typedef typename Last<Tail...>::Type Type;
};

template <class Head>
struct Last<Head> {
  typedef Head Type;
};

答案 1 :(得分:3)

您只能将decltype应用于表达式,而不应用于包。包非常特别,基本上总是需要扩展。您基本上遇到的问题是无法直接存储包:也不允许使用using type = T...

标准解决方案是将包存储在一些“容器模板”中,通常为tuple

using T = std::tuple<decltype(T{})...>;