![](/img/trans.png)
[英]Specialization of alias template best alternative without overhead in C++11
[英]C++11 alias template as template template argument in specialization?
为什么不遵循C ++ 11程序进行编译?
template<template<typename> class X, typename Y> struct C;
template<template<typename> class X, typename Z> struct C<X, X<Z>> {};
template<typename T> using A = T*;
int main()
{
C<A, A<int>> c;
}
错误是:
aggregate ‘C<A, int*> c’ has incomplete type and cannot be defined
为什么C
的部分专业化不匹配C<A, A<int>>
?
我认为 14.5.7别名模板:
当模板id是指一个别名模板的专业化,它相当于通过其模板参数在别名模板的类型-ID 模板参数替代所获得的相关的类型。
将会适用,因此只要已知X
是别名模板, X<Z>
就将解释为Z*
。 部分专门化的语法确实确实使用了template-id语法规则。 但是,只有在推导出所有模板参数后,模板参数替换才作为模板参数推导的最后一步。
14.5.5.1类模板部分专业化的匹配[temp.class.spec.match]
2如果可以从实际模板参数列表中推导出部分专用化的模板参数,则部分专用化将与给定的实际模板参数列表匹配。
14.8.2模板参数推导[temp.deduct]
5从默认模板参数推导或获取所有模板参数后,模板的模板参数列表和函数类型中所有模板参数的使用将替换为相应的推导或默认参数值。
如果没有X
模板参数替换,则无法推导Z
因此,专业化不匹配。
A<int>
是 int
,所以C<A, A<int>>
是 C<A, int>
。 该专业化无法匹配您想要的,因为它看不到A<int>
。
A
是别名模板,它实际上专门用于typedef名称。 A<int>
就像int *
的typedef一样。
C<A, A<int>>
与C<A, int *>
。 参数X
获得A
,参数Y
获得int *
。 为了推断部分专业化中的Z
应该是int
,编译器将必须检查别名定义内部。 别名不是这样工作的。 该定义是非推导上下文,即使将别名定义替换为部分专业化中的间接使用X<Z>
也会产生推论上下文。 此外,需要推测性地进行推论,以确定A
甚至可以是X
解决这个问题将是巨大的复杂负担。
正如您在std讨论列表中提到的,“永远不会推导出别名模板名称。”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.