编译时
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
来“修复”它,但是为什么/为什么这首先被认为是模棱两可的?
最佳答案
您正在将 int
传递给这个重载函数。
虽然人类的直觉认为 ambig(signed long)
应该是首选,因为您的输入是一个负整数(不能用 unsigned long
表示) ,这两个转换在 C++ 中的“优先级”实际上是等价的。
也就是说,转换 int
→ unsigned long
被认为与 int
→ signed long
一样有效code>,两者都不如对方好。
另一方面,如果您的参数已经是 long
而不是 int
,则 完全匹配 signed long
,无需转换。 This avoids the ambiguity .
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(static_cast<long>(-1)); return 0; }
“只是其中之一”。
[C++11: 4.13/1]:
("Integer conversion rank")Every integer type has an integer conversion rank defined as follows:
- [..]
- The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size.
- The rank of
long long int
shall be greater than the rank oflong int
, which shall be greater than the rank ofint
, which shall be greater than the rank ofshort int
, which shall be greater than the rank of signed char.- The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
- [..]
[ Note: The integer conversion rank is used in the definition of the integral promotions (4.5) and the usual arithmetic conversions (Clause 5). —end note ]
重载决议很复杂,定义在[C++11: 13.3]
;我不会在这里引用其中的大部分内容来让您感到厌烦。
不过这里有一个亮点:
[C++11: 13.3.3.1/8]:
If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion (13.3.3.1.1).
[C++11: 13.3.3.1/9]:
If no sequence of conversions can be found to convert an argument to a parameter type or the conversion is otherwise ill-formed, an implicit conversion sequence cannot be formed.
[C++11: 13.3.3.1/10]:
If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is indistinguishable from any other user-defined conversion sequence134. If a function that uses the ambiguous conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is ambiguous.
/10
是您遇到的情况;/8
是您使用long
参数的情况。
关于c++ - 为什么用整数文字调用重载的 ambig(long) 和 ambig(unsigned long) 会产生歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31935189/