【发布时间】:2014-08-17 11:47:44
【问题描述】:
我在将可变参数模板解压缩为模板别名时遇到了问题。
以下代码适用于 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 中进行了更改。这适用于大多数模板,但会导致别名模板出现问题。
在大多数情况下,别名模板是透明的;当它在模板中使用时,我们可以替换依赖的模板参数。但是,如果模板 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...>);没有办法用
S来表达A<Ts...>,所以我们需要保持A直到我们有Ts可以替换,因此需要在mangling中处理.目前,EDG 和 Clang 拒绝了这个测试用例,抱怨 A 的模板参数太少。G++ 也这样做了,但我认为这是一个错误。然而,在 ABI 列表中,John Spicer 认为它应该被拒绝。
【问题讨论】:
-
你能把
front_type移到foo之外吗?它们似乎不相关? -
是的,好点@PiotrNycz。 (但它并没有解决它。)
-
我用 gcc4.8 检查了这个修改后的代码 - 看起来它可以工作。
-
"works with Clang 3.4" 然而,这被 clang 3.5.0 拒绝了:
error: pack expansion used as argument for non-pack parameter of alias template
标签: c++ c++11 variadic-templates gcc4.9 template-aliases