Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么用整数文本调用重载的ambig(long)和ambig(unsigned long)是不明确的?_C++_Visual C++_Ambiguity - Fatal编程技术网

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

尽管人类直觉认为 AppId(签署long)应该是首选的,因为您的输入是负整数(不能用“代码>未签名的长< /COD>”来表示),这两个转换实际上在C++中的“优先”中等价。 也就是说,转换

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-long-int
    的秩应大于long-int的秩,后者应大于
    int
    的秩,后者应大于
    short-int
    的秩,后者应大于有符号字符的秩
  • 任何无符号整数类型的秩应等于相应有符号整数类型的秩。
  • [……]
[注:整数转换等级用于定义整数升迁(4.5)和常用算术转换(第5条)。-结束注]

重载解析很复杂,在
[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; }