我遇到了将可变参数模板解压缩为模板别名的问题。
以下代码适用于 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++ 核心语言问题 #1430 的一些上下文,“将扩展打包到固定别名模板参数列表中”:
最初,包扩展无法扩展为固定长度的模板参数列表,但在 N2555 中进行了更改。这适用于大多数模板,但会导致别名模板出现问题。
在大多数情况下,别名模板是透明的;当它在模板中使用时,我们可以替换依赖的模板参数。但是,如果模板 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
s 可以替换,因此需要在 mangling 中处理。目前,EDG 和 Clang 拒绝了这个测试用例,抱怨 A 的模板参数太少。G++ 也是如此,但我认为这是一个错误。然而,在 ABI 名单上,John Spicer 认为它应该被拒绝。