我很难理解演绎在以下情况下的工作原理:
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
最佳答案
Why a1 is not deduced in this context?
因为 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
.那是棘手的。因此元函数的映射只是单行道。您不能要求编译器从目标类型推断出源类型(或非类型参数)。
关于c++ - 模板特化和别名模板推导区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55967949/