在模板别名中解压缩参数包

时间:2014-06-26 14:50:18

标签: c++ c++11 variadic-templates gcc4.9 template-aliases

我遇到了将可变参数模板解压缩到模板别名中的问题。

以下代码适用于Clang 3.4和GCC 4.8,但GCC 4.9失败:

template <typename T, typename...>
using front_type = T;

template <typename... Ts>
struct foo
{
  using front = front_type<Ts...>;
};

GCC 4.9抱怨:

test.cc:7:37: error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ...> using front_type = T'
       using front = front_type<Ts...>;
                                     ^
test.cc:1:15: note: declared here
     template <typename T, typename...>
               ^

存在一个提交的GCC错误(#59498),但这应该失败吗?以下是C++ core language issue #1430, "pack expansion into fixed alias template parameter list"

的一些背景信息
  

最初,包扩展无法扩展到固定长度的模板参数列表,但在N2555中已更改。这适用于大多数模板,但会导致别名模板出现问题。

     

在大多数情况下,别名模板是透明的;当它在模板中使用时,我们可以在依赖模板参数中替换。但是,如果template-id对非可变参数使用包扩展,则这不起作用。例如:

  template<class T, class U, class V>
  struct S {};

  template<class T, class V>
  using A = S<T, int, V>;

  template<class... Ts>
  void foo(A<Ts...>);
     

无法用A<Ts...>来表达S,因此我们需要保留A,直到我们有T来代替,因此需要在整理中处理。

     

目前,EDG和Clang拒绝这个测试用例,抱怨A.G ++的模板参数太少,但我认为这是一个错误。然而,在ABI名单上,John Spicer认为它应该被拒绝。

1 个答案:

答案 0 :(得分:10)

gcc4.9报道了bugzilla:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

重现的最小代码

template <typename T, typename ...>
using alias = T;

template <typename ...T>
using variadic_alias = alias<T...>;

using Fail = variadic_alias<int>;

int main() { }

根据gcc人员的解释 - 这不是一个真正的错误。 这仍然是在gcc bugzilla和DR 1430(http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430)中进行的讨论 - 现在在上面的问题中进行了总结。