#include <utility>
class A {
int* ptr;
public:
A() {
ptr = new int[10];
}
A(A&& rhs) {
this->ptr = rhs.ptr;
rhs.ptr = nullptr;
}
~A() {
if (ptr) delete[] ptr;
}
};
int main() {
A a1;
A a2;
a2 = std::move(a1);
}
Run Code Online (Sandbox Code Playgroud)
GCC 11 抱怨复制赋值运算符被删除:
<source>: In function 'int main()':
<source>:23:22: error: use of deleted function 'constexpr A& A::operator=(const A&)'
23 | a2 = std::move(a1);
| ^
<source>:3:7: note: 'constexpr A& A::operator=(const A&)' is implicitly declared as deleted because 'A' declares a move constructor or move assignment operator
3 | class A {
| ^
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
然后,在我定义了移动赋值运算符(不是复制赋值运算符)之后,它编译得很好。那么,这意味着编译器确实正在寻找移动赋值运算符,这正是我所期望的。我不明白为什么当隐式删除移动赋值运算符时,编译器会寻找复制赋值运算符。任何想法?或者这只是编译器发出的错误消息?
你的解释并不完全正确。编译器并没有特别寻找operator=(A&&). 它只是在寻找任何operator=可以被要求执行该任务的人。
现在,移动赋值运算符operator=(A&&)根本不存在。但是,复制赋值运算符operator=(const A&)确实存在,但它被定义为已删除。
因此,复制赋值运算符是唯一可用于该赋值的运算符(因为常量左值引用可以绑定右值)。编译器尝试使用它,但发现它已被删除,从而触发编译错误。