为什么这些超载不明确?

时间:2013-05-26 22:29:19

标签: c++ templates overload-resolution ambiguous-call

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

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

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

1 个答案:

答案 0 :(得分:7)

这两个重载都是可行的,但前者比后者更专业,因此它会被重载决策选中。

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

  

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

     

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

     

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

     

- F1是非模板函数,F2是函数模板特化,或者,如果不是,

     

- F1F2是功能模板专精,F1的功能模板更专业   根据14.5.6.2中描述的偏序规则,F2的模板。

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

  

部分排序通过变换选择两个函数模板中哪一个比另一个更专业   每个模板轮流(参见下一段)并使用该函数执行模板参数推导   类型。演绎过程确定其中一个模板是否比另一个模板更专业。如果   因此,更专业的模板是部分订购流程选择的模板。