我遇到了将可变参数模板解压缩到模板别名中的问题。
以下代码适用于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认为它应该被拒绝。
答案 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)中进行的讨论 - 现在在上面的问题中进行了总结。