为什么这些超载不明确?

HC4*_*ica 7 c++ templates ambiguous-call overload-resolution

以下代码使用gcc和clang编译好.

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

template <typename T>
void foo(typename identity<T>::type);

template <typename T>
void foo(T);

int main()
{
    foo<int>(0);
}
Run Code Online (Sandbox Code Playgroud)

看起来重载决策是选择第一个重载(identity<T>::type一个).

有人可以解释为什么重载不是模棱两可的吗?据我所知,它们之间唯一的区别是第一个的参数是非推导的上下文而第二个的参数不是,但是因为我明确地提供了模板参数,所以我不赞成不明白为什么这很重要.

And*_*owl 7

两种重载都是可行的,但前者比后者更专业,因此它可以通过重载决策来选择.

根据关于重载决策的C++ 11标准的第13.3.3/1段:

[...] 如果对于所有参数,可行函数F1被定义为比另一个可行函数更好的函数 ,并不是比转换序列更差的转换序列,然后F2iICSi(F1)ICSi(F2)

- 对于某些参数j,ICSj(F1)是一个更好的转换序列ICSj(F2),或者,如果不是,

- 上下文是由用户定义的转换初始化(见8.5,13.3.1.5和13.3.1.6)以及从返回类型F1到目标类型的标准转换序列(即,正在初始化的实体的类型)是一种比从返回类型F2到目标类型的标准转换序列更好的转换序列.[...]或者,如果不是,

- F1是非模板函数,F2是一个函数模板特化,如果不是,

- F1并且F2是函数模板特化,并且函数模板F1F2根据14.5.6.2中描述的部分排序规则的模板更专业.

第14.5.6.2/2段概述了确定两个功能模板中哪一个比另一个更专业的过程:

部分排序通过依次转换每个模板(参见下一段)并使用函数类型执行模板参数推导来选择两个函数模板中哪一个比另一个更专业.演绎过程确定其中一个模板是否比另一个模板更专业.如果是这样,则更专业的模板是由部分排序过程选择的模板.