为什么以下重载函数调用不明确?编译错误:
call of overloaded 'test(long int)' is ambiguous,candidates are: void test(A)| void test(B)|
代码:
class A
{
public:
A(int){}
A(){}
};
class B: public A
{
public:
B(long){}
B(){}
};
void test(A a)
{
}
void test(B b)
{
}
void main()
{
test(0L);
return;
}
最佳答案
你得到了一个错误,因为重载决议必须从两个同样可行的函数中选择(都有用户定义的转换)。函数重载决议是一个非常复杂的主题。有关重载决议的更多详细信息,请参见例如这个recent lecture斯蒂芬·T·拉瓦维 (Stephan T. Lavavej)。通常最好使单参数构造函数显式
,然后使用显式构造函数参数调用您的函数。
test(0L)
与任何重载都不完全匹配,因为没有重载 test(long)
。您提供的两个重载都对它们的参数进行了用户定义的转换,但编译器认为它们同样可行。 A
重载必须执行标准转换(long 到 int),然后执行用户定义的转换(int 到 A),B
重载用户定义的转换(长到 B)。但两者都是隐式用户定义的转换序列。
这些排名如何?该标准在13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
中说Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 is a proper subsequence of 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()
。
关于c++ - 为什么这些重载函数调用不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11880585/