In the following program struct S
provides two conversion operators: in double
and in long long int
. Then an object of type S
is passed to a function f
, overloaded for float
and double
:
struct S {
operator double() { return 3; }
operator long long int() { return 4; }
};
void f( double ) {}
void f( float ) {}
int main() {
S s;
f( s );
}
MSVC compiler accepts the program fine, selecting f( double )
overload. However both GCC and Clang see an ambiguity in the calling of f
, demo: https://gcc.godbolt.org/z/5csd5dfYz
It seems that MSVC is right here, because the conversion:
operator long long int()
-> f( float )
is not a promotion. Is it wrong?
There is a similar question Overload resolution with multiple functions and multiple conversion operators, but there is a promotion case in it and all compilers agree now, unlike the case in this question.
The process of matching function calls to a specific overloaded function is called overload resolution. Just because there is no exact match here doesn't mean a match can't be found -- after all, a char or long can be implicitly type converted to an int or a double .
In Function overloading, sometimes a situation can occur when the compiler is unable to choose between two correctly overloaded functions. This situation is said to be ambiguous. Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile.
prog.cpp:25:12: error: call of overloaded ‘test (float)’ is ambiguous The above code will throw an error because the test (2.5f) function call will look for float function if not present it is only promoted to double, but there is no function definition with double or float type of parameter.
First of all, what is function overloading? Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures. This feature is present in most of the Object Oriented Languages such as C++ and Java. But C (not Object Oriented Language) doesn’t support this feature.
GCC and Clang are correct. The implicit conversion sequences (user-defined conversion sequences) are indistinguishable.
[over.ics.rank]/3:
(emphasis mine)
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
...
(3.3) User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.
The user-defined conversion sequences involves two different user-defined conversion functions (operator double()
and operator long long int()
), so compilers can't select one; the 2nd standard conversion sequence won't be considered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With