似乎可以在别名模板的pack参数的位置扩展 包参数。对于类或函数模板,情况并非如此:
template <class T, class... Args> struct x { using type = T; };
template <class T, class... Args> using x_t = typename x<T, Args...>::type;
template <class... Args> using x_fix_t = typename x<Args...>::type;
template <class... Args> auto f(Args...) -> void {
typename x<Args...>::type v1; // OK
x_t<Args...> v2; // Error
x_fix_t<Args...> v3; // OK
}
更简单的案例:
template <class T, class U> using y_t = T;
template <class... Args> auto f(Args...) -> void {
y_t<Args...> v4; // Error
}
以上代码在f
,c++11
和{{1}中同时生成错误(即使c++14
从未实例化)g++ 4.9
和g++ 5.1
}。
为什么不允许这样做,一般规则是什么?我认为没有理由限制这一点。这似乎是一个非常奇怪的禁令。
至于为什么不用第一个变体写clang 3.5
,更清楚x_fix_t
有一个强制性的第一个参数。 (例如,这是不允许x_t
的原因)。但这并不重要,修复很容易。问题仍然存在:为什么?
gcc错误:
f()
clang错误:
error: pack expansion argument for non-pack parameter ‘T’ of
alias template ‘template<class T, class ... Args> using x_t = typename x::type’
答案 0 :(得分:19)
这在GCC 4.8中编译但在GCC 4.9中失败,这证明它与DR1430和bug report #59498有关。 Roy Chrihfield提出的解决方案与你的完全相同:
Rewriting the code to use a struct succeeds:
template <typename T, typename ...>
struct alias { using type = T; };
template <typename ...T>
using variadic_alias = typename alias<T...>::type;
此外,Jason Merrill详细说明了它为什么会失败:
实际上,不,这是Core 1430的一个问题;没有办法 mangle variadic_alias没有提到别名的名称 在整修中的模板,它们应该是完全的 透明。这仅在4.8中偶然起作用,因为检查是 禁用此版本。
错误报告中不存在进一步的讨论,因此我们可以转向DR1430:
最初,包扩展无法扩展到固定长度 模板参数列表,但在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...>);
没有办法用S来表达A,所以我们需要坚持 在A上直到我们有Ts代替,因此它 需要在整理中处理。
目前,EDG和Clang拒绝这个测试用例,也抱怨 A. G ++的一些模板参数也是如此,但我认为是 一个bug。然而,在ABI名单上,John Spicer认为它应该是 拒绝。
(另见问题1558。)
2012年10月会议的说明:
CWG的共识是禁止使用这种用法, 当依赖参数不能使用别名模板时,禁止使用别名模板 只需直接替换为type-id。
附加说明,2013年4月:
再举一个例子,考虑一下:
template<class... x> class list{}; template<class a, class... b> using tail=list<b...>; template <class...T> void f(tail<T...>); int main() { f<int,int>({}); }
此示例的处理存在实现差异。
换句话说,这是一个持续的问题,没有任何解决方案(AFAIC)。