这不编译
#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都拒绝编译此代码段。
锵:
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的定义没有显式声明一个移动构造函数,那么只有在以下情况下才会将其隐式声明为默认值:
我错过了什么?
答案 0 :(得分:7)
没有用户声明的复制赋值运算符
恰恰相反:
keyboardInput
这仍然是用户声明的复制赋值运算符,只是S& operator=(const S& o) = delete;
d的运算符。它会阻止复制构造函数,移动构造函数并隐式生成赋值运算符。
delete
d的东西与根本不存在的东西不同; delete
声明了事物,但如果通过重载解析选择它们,则会产生错误。
您可以delete
移动分配并构建特殊成员函数,如果您希望它们存在,尽管您进行了=default
d副本分配。