c++ - 模板特化和别名模板推导区别

标签 c++ c++11 templates template-meta-programming 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)
{
}

测试代码如下:

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/

相关文章:

c++ - 在哪里以及为什么我必须放置 "template"和 "typename"关键字?

std::multimap 中的 c++ 枚举类

c++ - 为什么缺少/未声明 MonitorFromWindow? (C++/WinAPI)

c++ - std::arg 为实际输入返回不正确的值(使用 MSVC 编译器)

c++ - 如何在编译时使用 C++ 模板存储递归函数的中间结果?

c++ - 当对共享数据的所有引用都被序列化时,为什么函数是线程安全的?

c++ - 序列点和评估顺序(预增量)

c++ - 存储在结构中的元素是否彼此相邻

c++ - 模板类的方法使用全局范围内的 typedef。编译器错误?

javascript - 下划线模板中的 bool 检查