https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89596

            Bug ID: 89596
           Summary: [8 regression] Multiple templated conversion operators
                    result in compilation error
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jleahy+gcc at gmail dot com
  Target Milestone: ---

The follow code compiles fine on GCC <=7.4 (and also on Clang). However on 8.0
(and trunk) it fails.

template<typename T>
struct Bar {
    Bar() = default;
    Bar(double x) {}
};

struct Foo {
    template<typename T>
    operator T() {
        return T();
    }
    template<typename T>
    operator Bar<T>() {
        return Bar<T>();
    }
};

void test() {
    (void)static_cast<Bar<int>>(Foo());
}

The following error is produced:

<source>: In function 'void test()':
<source>:20:38: error: call of overloaded 'Bar(Foo)' is ambiguous
     (void)static_cast<Bar<int>>(Foo());
<source>:5:5: note: candidate: 'Bar<T>::Bar(double) [with T = int]'
     Bar(double x) {}
<source>:3:8: note: candidate: 'constexpr Bar<int>::Bar(const Bar<int>&)'
 struct Bar {
<source>:3:8: note: candidate: 'constexpr Bar<int>::Bar(Bar<int>&&)'

I believe from the standard GCC should consider all converting constructors (of
which there are none applicable) and user-defined conversion operators (of
which both are applicable) then apply normal overload resolution. During
overload resolution one of the two conversion operators will be discarded as
it's less specialized than the other.

Reply via email to