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

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Minimal testcase:

struct allocator { };

struct string {
  string(const string&);
  string(const allocator&);
};

struct NotString : allocator { };

struct String {
  operator string() const;
  operator NotString() const;
};

struct Message {
  template<typename T>
    Message(T&& t) : s{t} { }
  string s;
};

int main()
{
  String s;
  Message m(s);
}

This is rejected by GCC 8:

s.cc: In instantiation of ‘Message::Message(T&&) [with T = String&]’:
s.cc:24:14:   required from here
s.cc:17:25: error: call of overloaded ‘string(<brace-enclosed initializer
list>)’ is ambiguous
     Message(T&& t) : s{t} { }
                         ^
s.cc:5:3: note: candidate: ‘string::string(const allocator&)’
   string(const allocator&);
   ^~~~~~
s.cc:4:3: note: candidate: ‘string::string(const string&)’
   string(const string&);
   ^~~~~~

EDG also rejects it:

"s.cc", line 17: error: more than one instance of constructor "string::string"
          matches the argument list:
            function "string::string(const string &)"
            function "string::string(const allocator &)"
            argument types are: (String)
      Message(T&& t) : s{t} { }
                        ^
          detected during instantiation of "Message::Message(T &&) [with
                    T=String &]" at line 24


It's accepted by Clang.

Reply via email to