C ++重载分辨率模糊不清 - GCC

时间:2014-01-21 19:13:21

标签: c++ gcc c++11 standards overload-resolution

我试图理解为什么GCC在下面的代码中选择f(char, A<C, 5> &var)进行重载解析:

template <class C, int N> struct A { };
template <class C> struct A<C, 8> { static_assert(sizeof(C) > 8, "Assertion in A<C,8>"); };
template <class C> struct A<C, 5> { static_assert(sizeof(C) < 8, "Assertion in A<C,5>"); operator A<C,8>&(); };

template <class C> void f(double, A<C,8> &var);
template <class C> void f(char, A<C,5> &var);

int main(void)
{
    A<int, 5> a;
    f(4., a);
}

有两种可用的重载:

template <class C> void f(double, A<C,8> &var);

4.完全匹配double(不需要隐式转换),但第二个参数需要用户定义的转换。所以这个重载:exact match&amp; user-define conversion

下一个重载,由GCC匹配:

template <class C> void f(char, A<C,5> &var);

4.要求隐式转换为char,但与A<C,5>完全匹配。 GCC是否有理由选择此超载而不是之前的?

有人可以从标准的第13部分找到有关此特定案件的证据吗?任何帮助或评论表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:5)

扣除不能成功

template <class C> void f(double, A<C,8> &var);

A<int, 5>类型的参数。即没有可能的C类型可以使A<C,8>与参数类型A<int,5>匹配。转换是可能的并不关心扣除。

见[temp.deduct.call] / 4。由于转换构造函数和转换函数可以允许转换,因此无法考虑(所有)转换类型推导。这也可能导致含糊不清。