GCC seems to have a non-standard lenient C++ overload resolution that is not documented (or easy to find in the manual).

The following C++ code compiles with GCC. However, it produces a warning about an ambiguous overload that apparently is not acceptable by the standard. Clang and MVSC simply reject the code because of the ambiguous overload.

```
// reduced example
#include <iostream>
using namespace std;
struct A{};
struct B: public A {};
struct C{};
struct D{ D() = default; D(const C&){}; };

void p( A&, const C& ){ cout << "AC\n"; };
void p( B&, const D& ){ cout << "BD\n"; };

int main() {
    B b; C c;
    p(b,c); // ambiguous call
    return 0;
}
```

GCC detects ambiguity in which `p` to choose: either cast from derived class B& to base class A& or construct D from C.

```
$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:51:10: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   51 |         p(b,c);
      |         ~^~~~~
test.cpp:12:6: note: candidate 1: ‘void p(A&, const C&)’
   12 | void p( A&, const C& ){ cout << "AC\n"; };
      |      ^
test.cpp:15:6: note: candidate 2: ‘void p(B&, const D&)’
   15 | void p( B&, const D& ){ cout << "BD\n"; };
      |      ^
```

With `-pedantic` it does not compile anymore. I subjectively agree with GCC that the first choice is better than the second. But not everyone may do so. Is there a documentation of all these deviations from the standard?

Reply via email to