重载决策和显式模板参数

时间:2016-09-04 18:22:01

标签: c++ template-specialization overload-resolution

以下代码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);    
}

1 个答案:

答案 0 :(得分:3)

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

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

请注意,模板部分排序规则在标准中有些不完整。如果您只是添加另一个T类型的参数,则优先选择flips