http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60631
Bug ID: 60631 Summary: [c++11] rvalue this member functions are ambiguous Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: paul at preney dot ca Created attachment 32433 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32433&action=edit Brief code illustrating ambiguity bug. The attached code using rvalue *this qualified member functions and fails to compile although it should. The attached code produces the following ambiguous error message which only arises from the use of a const rvalue object: $ g++ -std=c++11 -Wall -Wextra gcc-rvalue-this-ambig-issue.cxx gcc-rvalue-this-ambig-issue.cxx: In function ‘int main()’: gcc-rvalue-this-ambig-issue.cxx:33:29: error: call of overloaded ‘get()’ is ambiguous gobble(std::move(t).get()); // GCC reports this line is ambiguous! ^ gcc-rvalue-this-ambig-issue.cxx:33:29: note: candidates are: gcc-rvalue-this-ambig-issue.cxx:10:14: note: const int& Type::get() const & int const& get() const& { return i; } ^ gcc-rvalue-this-ambig-issue.cxx:15:15: note: const int&& Type::get() const && int const&& get() const&& { return std::move(i); } ^ gcc-rvalue-this-ambig-issue.cxx:17:24: note: const volatile int&& Type::get() const volatile && int const volatile&& get() const volatile&& { return std::move(i); } ^ $ with g++ v4.9.0 (Mar. 16). This error is also reported with g++ v4.8.1 and v4.8.2. (Aside: Know the attached code compiles without issue with clang++ v3.4.) Significantly the above error shows g++ is also incorrectly considering an lvalue ref qualified get() member even though the object is an rvalue due to the use of std::move(). Finally, this ambiguity error ONLY occurs when Type is decorated with const: { Type const t; gobble(t.get()); gobble(std::move(t).get()); // GCC reports this line is ambiguous! } whereas in all other cases of Type, Type volatile, and Type const volatile there is no ambiguity. The definition of Type has all rvalue *this and cv-qualifiers overloaded for the get() member function, i.e., which implies there should be no ambiguity which function gets called as there is always an exact match. struct Type { int i; Type() : i(0) { } int& get() & { return i; } int const& get() const& { return i; } int volatile& get() volatile& { return i; } int const volatile& get() const volatile& { return i; } int&& get() && { return std::move(i); } int const&& get() const&& { return std::move(i); } int volatile&& get() volatile&& { return std::move(i); } int const volatile&& get() const volatile&& { return std::move(i); } }; I cannot think of a good work-around other than to drop back (for the time being) and not use rvalue *this members until this is fixed. I thank you for looking at this issue.