编译时
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(-1); return 0; }
我明白了
error C2668: 'ambig' : ambiguous call to overloaded function
could be 'void ambig(unsigned long)'
or 'void ambig(long)'
while trying to match the argument list '(int)'
我知道我可以通过说 -1L
而不是 -1
,但为什么/如何在一开始就被认为是模棱两可的?
3 回答
您正在将
int
传递给此重载函数 .虽然人类的直觉说_1336250应该是首选,因为你的输入是一个负整数(不能用
unsigned long
表示),这两个转换在C中实际上等同于"precedence" .也就是说,转换
int
→unsigned long
被认为与int
→signed long
一样有效,并且两者都不优先 .另一方面,如果您的参数已经是
long
而不是int
,则与signed long
完全匹配,无需转换 . This avoids the ambiguity .“只是其中之一” .
重载分辨率很复杂,在
[C++11: 13.3]
中定义;我不会在这里引用大部分内容而烦恼你 .不过,这里有一个亮点:
/10
就是你遇到的情况;/8
是您使用long
参数的情况 .常量
-1
的类型为int
. 所以你用int
作为参数调用ambig
.ambig
没有接受int
的重载,因此我们必须查看我们可以执行的隐式转换 .int
可以隐式转换为long
或unsigned long
(以及其他内容),这两者都是ambig
的有效参数 . 所以编译器不知道要选择哪个转换,你需要手动转换(或使用长常量(-1l
)而不是int常量开始) .-1
是一个负数这一事实并没有看到参数值,只是它的类型 .因为
-1
的类型为int
. 并且int
可以隐式转换为signed long
或unsigned long
.