未隐式声明的移动赋值运算符
Move assignment operator not being implicitly declared
这不编译
#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 的定义没有显式声明移动构造函数,则当且仅当
:- X 没有用户声明的复制构造函数,
- X 没有用户声明的复制赋值运算符,
- X 没有用户声明的移动分配运算符,并且
- X 没有用户声明的析构函数。
我错过了什么?
没有
用户声明的复制赋值运算符,
相反:
S& operator=(const S& o) = delete;
这仍然是用户声明的复制赋值运算符,只是一个delete
D 运算符。 它阻止隐式生成复制构造函数、移动构造函数和移动赋值运算符。
被delete
的东西与它根本不存在是不一样的; 声明delete
事物,但如果通过重载解析选择,它们将生成错误。
您可以=default
移动赋值并构造特殊成员函数,如果希望它们存在,尽管您delete
复制赋值。
相关文章:
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 对 r 值使用移动赋值运算符时的异常
- 为什么定义移动构造函数会删除移动赋值运算符
- C++中移动赋值运算符的继承
- 为什么对象可以"moved"甚至缺少移动构造函数和移动赋值运算符?
- 移动赋值运算符与复制赋值运算符
- 查找所有移动构造函数和移动赋值运算符(特别是那些没有"noexcept"的运算符)
- 移动构造函数和移动赋值运算符与复制省略
- 未隐式声明的移动赋值运算符
- 如何使用继承(抽象基类)实现移动构造函数和移动赋值运算符
- 未调用移动赋值运算符
- 移动赋值运算符和移动构造函数之间的区别
- 外部C结构的C++默认复制/移动赋值运算符不是常量
- C++移动语义:为什么调用复制赋值运算符=(&)而不是移动赋值运算符=(&&)?
- 为什么移动构造函数和移动赋值运算符被调用而不是复制
- 在什么场景中,我应该明确需要实现移动构造函数和移动赋值运算符
- 在 C++98 中实现移动构造函数和移动赋值运算符以获得更好的性能
- 通过在移动赋值运算符中使用std::swap来重用析构函数逻辑有意义吗
- 未调用/继承子类中的移动赋值运算符
- 为一个简单的派生类编写移动赋值运算符