【发布时间】:2017-12-24 00:34:51
【问题描述】:
这不会编译
#include <utility>
struct S {
int x;
S& operator=(const S& o) = delete;
// Uncomment this to compile
//S& operator=(S&& o) = default;
};
int main() {
S s1, s2;
s1.x = 0;
s2.x = 101;
// Following 2 lines do not compile
s1 = std::move(s2);
s1 = static_cast<S&&>(s2);
return 0;
}
clang 3.8.1 和 g++ 6.3.0 都拒绝编译这个 sn-p。
叮当声:
c.cc:19:6: error: overload resolution selected deleted operator '='
s1 = std::move(s2);
~~ ^ ~~~~~~~~~~~~~
c.cc:6:6: note: candidate function has been explicitly deleted
S& operator=(const S& o) = delete;
G++:
c.cc: In function ‘int main()’:
c.cc:19:20: error: use of deleted function ‘S& S::operator=(const S&)’
s1 = std::move(s2);
^
c.cc:6:6: note: declared here
S& operator=(const S& o) = delete;
^~~~~~~~
我了解=delete 并没有禁止复制赋值运算符参与重载解析,但为什么会导致隐式声明的移动赋值运算符被删除?
C++ 标准说 (12.8/9):
如果类 X 的定义没有显式声明移动构造函数,当且仅当:
- X 没有用户声明的复制构造函数,
- X 没有用户声明的复制赋值运算符,
- X 没有用户声明的移动赋值运算符,并且
- X 没有用户声明的析构函数。
我错过了什么?
【问题讨论】:
-
您引用了回答您问题的文字。您的 S 有一个用户声明的复制赋值运算符,因此没有隐式声明的移动构造函数。