C++ 为什么用整数文本调用重载的ambig(long)和ambig(unsigned long)是不明确的?
编译时C++ 为什么用整数文本调用重载的ambig(long)和ambig(unsigned long)是不明确的?,c++,visual-c++,ambiguity,C++,Visual C++,Ambiguity,编译时 void ambig( signed long) { } void ambig(unsigned long) { } int main(void) { ambig(-1); return 0; } 我明白了 我知道我可以通过说-1L而不是-1来“修复”它,但是为什么/如何确切地说这被认为是含糊不清的呢?因为-1是int类型。而int可以隐式转换为signed long或unsigned long您正在向这个重载函数传递int 尽管人类直觉认为 AppId(签署long)应该是首选的
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(-1); return 0; }
我明白了
我知道我可以通过说
-1L
而不是-1
来“修复”它,但是为什么/如何确切地说这被认为是含糊不清的呢?因为-1
是int
类型。而int
可以隐式转换为signed long
或unsigned long
您正在向这个重载函数传递int
尽管人类直觉认为
→ int
被认为与unsigned long
→ <代码>长签名,两者都不是首选项int
long
而不是int
,则与有符号long
完全匹配,无需转换
void ambig(有符号长){
void ambig(无符号长){}
int main(void){ambig(static_cast(-1));返回0;}
“只是其中之一”
[C++11:4.13/1]:
(“整数转换秩”)
每个整数类型都有一个整数转换秩,定义如下:
- [……]
- 有符号整数类型的秩应大于任何较小的有符号整数类型的秩。
的秩应大于long-int的秩,后者应大于long-long-int
的秩,后者应大于int
的秩,后者应大于有符号字符的秩short-int
- 任何无符号整数类型的秩应等于相应有符号整数类型的秩。
- [……]
[C++11:13.3]
中定义;我不会在这里引用其中的大部分来让你厌烦
不过,这里有一个亮点:
[C++11:13.3.3.1/8]:
如果参数与参数类型匹配不需要任何转换,则隐式转换序列是由标识转换(13.3.3.1.1)组成的标准转换序列
[C++11:13.3.3.1/9]:
如果找不到将参数转换为参数类型的转换序列,或者转换格式不正确,则无法形成隐式转换序列
[C++11:13.3.3.1/10]:
如果存在多个不同的转换序列,每个序列都将参数转换为参数类型,则与参数关联的隐式转换序列被定义为指定为不明确转换序列的唯一转换序列。为了对13.3.3.2中所述的隐式转换序列进行排序,不明确的转换序列被视为与任何其他用户定义的转换序列134无法区分的用户定义序列。如果选择使用不明确转换序列的函数作为最佳可行函数,则调用的格式将不正确,因为调用中某个参数的转换不明确
是您正在经历的情况/10
是与/8
参数一起使用的情况长
-1
的类型为int
。因此,您使用int
作为参数调用ambig
ambig
没有接受int
的重载,因此我们必须查看可以执行的隐式转换。int
可以隐式转换为long
或无符号long
(除其他外),这两者都是ambig
的有效参数。因此,编译器不知道选择哪个转换,您需要手动强制转换(或者使用长常量(-1l
)而不是int常量)
-1
是负数这一事实并没有考虑到它,因为编译器不查看参数值,只查看其类型。等等,但是int
→ long
始终是无损转换<代码>整数→ <代码>无符号长有一半时间是有损的。他们怎么/为什么是同一级别?!只是好奇:有什么理由不使用-1L
来代替那个演员吗?@sepp2k:Wow,我明白了。。。o_uuo(“每日#$!”浮现在脑海中…@Mehrdad:上面第三个粗体的子弹。至于“为什么”,谁知道呢@Mehrdad:这可能是因为在典型的老式16位系统上,int
→ <代码>无符号长没有损耗(我相信?)。大概看起来有点傻。
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)'
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(static_cast<long>(-1)); return 0; }