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

            Bug ID: 92662
           Summary: change in gcc 8 vs 9: call of overloaded
                    ‘basic_string(<brace-enclosed initializer list>)’ is
                    ambiguous
           Product: gcc
           Version: 9.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: matz at gcc dot gnu.org
  Target Milestone: ---

A user of ours noted a difference in behaviour between gcc8 and gcc9 regarding
braced initializers.  Take this example:

---------------------------------------------
#include <string>

// allow to steal _text from rvalues
struct Test
{
  std::string const& str() const& { return _text; }
  std::string &&     str() &&     { return std::move(_text); }

  operator std::string const&() const& { return _text; }
  operator std::string &&    () &&     { return std::move(_text); }

  std::string _text;
};

int main()
{
  Test t;
  std::string a { std::move(t).str() };   // 1
  std::string b { std::move(t) };         // 2
  return 0;
}
---------------------------------------------

gcc 8 accepts the program (and str() && is chosen in line 1), whereas gcc 9
only accepts line 1 but not line 2 due to:

xorig.cc: In function ‘int main()’:
xorig.cc:19:32: error: call of overloaded ‘basic_string(<brace-enclosed
initializer list>)’ is ambiguous
   19 |   std::string b { std::move(t) };
      |                                ^
In file included from /usr/include/c++/9/string:55,
                 from xorig.cc:1:
/usr/include/c++/9/bits/basic_string.h:3628:7: note: candidate:
‘std::basic_string<_CharT, _Traits,
_Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with
_CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char>]’
 3628 |       basic_string(basic_string&& __str)
      |       ^~~~~~~~~~~~
/usr/include/c++/9/bits/basic_string.h:3564:7: note: candidate:
‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const
std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits =
std::char_traits<char>; _Alloc = std::allocator<char>]’
 3564 |       basic_string(const basic_string& __str);
      |       ^~~~~~~~~~~~


One difference is the temporary object
used for calling .str() in line 1.  But still I have difficulties to see
why there's a difference in ambiguities.

So, who's right (8 or 9), and due to which reasons.  (Depending on that this
is either an error in gcc 8 or 9, so I'm not marking it yet).

Reply via email to