Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloaded function and multiple conversion operators ambiguity in C++, compilers disagree

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.

like image 337
Fedor Avatar asked Nov 07 '21 07:11

Fedor


People also ask

How function calls are matched with overloaded functions?

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 .

What is ambiguity in C++ function overloading?

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.

What does error call of overloaded test (float) is ambiguous mean?

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.

What is function overloading in C programming?

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.


1 Answers

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.

like image 168
songyuanyao Avatar answered Oct 22 '22 10:10

songyuanyao