When compiling
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(-1); return 0; }
I get
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)'
I know I can 'fix' it by saying -1L
instead of -1
, but why/how exactly is this considered ambiguous in the first place?
You're passing an
int
to this overloaded function.Although human intuition says that
ambig(signed long)
ought to be preferred because your input is a negative integer (which cannot be represented as such by anunsigned long
), the two conversions are in fact equivalent in "precedence" in C++.That is, the conversion
int
→unsigned long
is considered to be just as valid asint
→signed long
, and neither is preferred to the other.On the other hand, if your parameter were already a
long
rather than anint
, then there is an exact match tosigned long
, with no conversion necessary. This avoids the ambiguity."Just one of those things".
Overload resolution is complex, and is defined in
[C++11: 13.3]
; I shan't bore you by quoting a majority of it here.Here's a highlight, though:
/10
is the case you're experiencing;/8
is the case you use with along
argument.