你得到了一个错误,因为重载解析必须从两个同样可行的函数中进行选择(两者都有用户定义的转换)。函数重载解析是一个非常复杂的主题。有关重载解决方案的更多详细信息,请参见Stephan T. Lavavej最近的讲座。通常最好制作单参数构造函数explicit
,然后使用显式构造函数参数调用您的函数。
test(0L)
与任何重载都不完全匹配,因为没有重载test(long)
。您提供的两个重载都对其参数进行了用户定义的转换,但编译器认为它们同样可行。重载必须执行A
标准转换(long 到 int),然后是用户定义的转换(int 到 A),B
重载是用户定义的转换(long 到 B)。但两者都是隐式用户定义的转换序列。
这些排名如何?标准在13.3.3.2 排名隐式转换序列 [over.ics.rank]
如果 S1 是 S2 的适当子序列,则标准转换序列 S1 是比标准转换序列 S2 更好的转换序列
例如,如果 A 是 B 的派生类(反之亦然),这些类型的平局就适用。但是这里没有一个转换序列是另一个的子序列。因此它们同样可行,编译器无法解析调用。
class A
{
public:
explicit A(int){}
A(){}
};
class B: public A
{
public:
explicit B(long){}
B(){}
};
void test(A a)
{}
void test(B b)
{}
int main()
{
test(A(0L)); // call first overload
test(B(0L)); // call second overload
return 0;
}
注意:它是int main()
,不是void main()
。