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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Harald van Dijk from comment #1)
> Your StringType provides a conversion operator to HTTPResponse, which
> indirectly has std::allocator<char> as a private base class. Overload
> resolution happens before access checks, so the fact that it is a private
> base class does not prevent the construction of std::string from being
> ambiguous: the conversion to HTTPResponse could be used followed by the
> construction of a new std::string using the HTTPResponse as the allocator.

Right, the code is equivalent to this:

#include <string>

struct NotString : std::allocator<char> { };

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

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

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


> This appears to work the same way in GCC 8 as it does in GCC 7, although it
> is possible that for whatever reason, the GCC 7 version ends up not
> including std::allocator<char> as a base class.

There was a change in overload resolution between GCC 7 and 8.

Reply via email to