模板专业化与别名模板推导的区别

时间:2019-05-03 10:28:18

标签: c++ c++11 templates template-meta-programming template-deduction

在以下情况下,我难以理解推论的作用:

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
{ };

两个工作。有人知道为什么吗?

[编辑] 与Mixing aliases and template specializations

相关的问题

1 个答案:

答案 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!
};

编译器将需要查看整个程序中的所有代码,并尝试所有类型,以确保没有发生任何恶意行为,以确保a1typename AHelper<Category, code>::type真正匹配。太难了因此,通过元功能进行的映射仅是单向路。您不能要求编译器从目标类型推断出源类型(或非类型参数)。