Sat*_*rnu 10 c++ templates template-meta-programming c++11 template-argument-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)
{
}
Run Code Online (Sandbox Code Playgroud)
以下是测试代码:
A<int, 5> a1;
doSomething(a1); // This does not compile
doSomething<5>(a1); // This compiles
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下不推导a1?
如果改用以下方式修改A:
template<class Category, Category code>
struct A
{ };
Run Code Online (Sandbox Code Playgroud)
两者都可以。有人知道为什么吗?
[edit]与混合别名和模板专业化相关的问题
为什么在这种情况下不推导a1?
因为的模板参数doSomething
出现在非推论上下文中。别名模板几乎完全代表其别名。您的定义如下:
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
Run Code Online (Sandbox Code Playgroud)
要推论code
,编译器将需要推导左侧的内容::
,这是一个非推论上下文。如果模板参数推导显示为作用域解析运算符左侧的参数,则模板推论甚至不会尝试推导。
并非没有道理,这是一个不可推论的背景。请记住,模板可能是专门的。我可以添加以下内容:
template<Category code>
struct AHelper<int, code>
{
using type = BImpl<code>; // My own class!
};
Run Code Online (Sandbox Code Playgroud)
编译器将需要查看整个程序中的所有代码,并尝试所有类型,以确保不会发生任何恶意事情,以确保a1
确实与as匹配typename AHelper<Category, code>::type
。太难了 因此,通过元功能进行的映射仅是单向路。您不能要求编译器从目标类型推断出源类型(或非类型参数)。