【发布时间】:2026-01-14 06:35:01
【问题描述】:
如果我定义了一个复制赋值运算符,该运算符使用 thing 类的值传递调用复制构造函数:
thing& operator= (thing x) {
和同一类的移动赋值运算符:
thing& operator= (thing&& x) {
尝试调用移动赋值会导致 gcc 出错:
error: ambiguous overload for ‘operator=’ (operand types are ‘thing’ and ‘std::remove_reference<thing&>::type {aka thing}’)
但是,如果复制分配改为使用按引用传递:
thing& operator= (thing& x) {
编译没问题,两个运算符都可以调用。为什么是这样?
完整的C++11测试代码:
#include <iostream>
#include <utility>
using namespace std;
class thing {
public:
thing () { }
thing (thing& x) {
cout << "Copy constructor.\n";
}
thing (thing&& x) {
cout << "Move constructor.\n";
}
thing& operator= (thing x) {
cout << "Copy assign using pass by value.\n";
return *this;
}
thing& operator= (thing&& x) {
cout << "Move assign.\n";
return *this;
}
};
int main (void) {
thing a, b;
// Invoke move assignment:
a = move(b);
return 0;
}
【问题讨论】:
-
在重载解析中有一个特殊规则,即
A类型的右值更喜欢绑定到A&&而不是A&。A&&与A没有对应的规则。 -
@T.C.
A&不是必须是左值吗? -
其实是的,我应该写
const A&。A&只绑定左值。
标签: c++ g++ move-semantics