#include <type_traits>
#include <iostream>
template<typename T>
struct Wrapper {
T value;
operator T&() & { std::cout << "call const ref" << std::endl; return this->value; }
operator const T&() const& { std::cout << "call const ref" << std::endl; return this->value; }
operator T&&() && { std::cout << "call move" << std::endl; return std::move(this->value); }
operator const T&() const&& = delete;
operator T&&() & = delete;
operator T&&() const& = delete;
};
class A {
public:
A& operator=(const A&) { std::cout << "use copy" << std::endl; return *this; }
A& operator=(A&&) { std::cout << "use move" << std::endl; return *this; }
};
int main() {
Wrapper<A> b;
A bb;
bb = std::move(b);
}
I compiled this code with gcc10.2, and get the following error
test.cc: In function ‘int main()’:
test.cc:24:21: error: ambiguous overload for ‘operator=’ (operand types are ‘A’ and ‘std::remove_reference<Wrapper<A>&>::type’ {aka ‘Wrapper<A>’})
24 | bb = std::move(b);
| ^
test.cc:17:12: note: candidate: ‘A& A::operator=(const A&)’
17 | A& operator=(const A&) { std::cout << "use copy" << std::endl; return *this; }
| ^~~~~~~~
test.cc:18:12: note: candidate: ‘A& A::operator=(A&&)’
18 | A& operator=(A&&) { std::cout << "use move" << std::endl; return *this; }
| ^~~~~~~~
But I tried the same code with clang in cppinsights.io, and compiled successfully. link
So, what cause the difference between gcc and clang?
And how do I change the Wrapper
to fix it?