重载解析和显式模板参数

Overload resolution and explicit template arguments

下面的代码prints "func 2".

为什么编译器在存在显式(未推导)模板参数的情况下将第二个模板视为更好的匹配项?为什么没有歧义?

我希望引用 C++ 标准。

#include <iostream>

template<class T>
struct identity
{
    typedef T type;
};

template<class T>
void func(T)
{
    std::cout << "func 1\n";
}

template<class T>
void func(typename identity<T>::type)
{
    std::cout << "func 2\n";
}

int main()
{
    func<int>(1);    
}

两个候选者都是可行的并且采用相同的参数,因此重载解决过程回退到最后一个决胜局:函数模板的偏序 [temp.func.order]

规则是我们为每个模板类型参数合成一个新类型,并尝试对彼此的重载进行推导。对于 1,我们合成了一个类型 Unique1,它在 2 上推导失败,因为 T 是一个非推导上下文。对于2,我们合成了一个类型Unique2,它成功推导了T = typename identity<Unique2>::type。由于演绎在一个方向上成功而不是另一个方向,这使得 21 更专业,因此它是首选。

请注意,模板部分排序规则在标准中有些不完整。如果您简单地添加另一个 T 类型的参数,首选项 .