在以下情况下,我难以理解推论的作用:
template<class Category, Category code>
struct AImpl
{ };
template<class Category, Category code>
struct AHelper
{
using type = AImpl<Category, code>;
};
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
template<int code>
void doSomething(A<int, code> object)
{
}
以下是测试代码:
A<int, 5> a1;
doSomething(a1); // This does not compile
doSomething<5>(a1); // This compiles
为什么在这种情况下不推导a1?
如果您通过以下方式修改A:
template<class Category, Category code>
struct A
{ };
两个工作。有人知道为什么吗?
相关的问题答案 0 :(得分:9)
为什么在这种情况下不推导a1?
因为doSomething
的模板参数出现在非推论上下文中。别名模板几乎完全代表其别名。您的定义如下:
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
要推论code
,编译器将需要推论::
左侧的内容,这是一个非推论上下文。如果模板参数推导显示为作用域解析运算符左侧的参数,则模板推论甚至不会尝试推导。
这不是没有道理的上下文。请记住,模板可能是专门的。我可以添加这个:
template<Category code>
struct AHelper<int, code>
{
using type = BImpl<code>; // My own class!
};
编译器将需要查看整个程序中的所有代码,并尝试所有类型,以确保没有发生任何恶意行为,以确保a1
与typename AHelper<Category, code>::type
真正匹配。太难了因此,通过元功能进行的映射仅是单向路。您不能要求编译器从目标类型推断出源类型(或非类型参数)。