如果我们只定义复制构造函数/oper=,为什么移动构造函数/move赋值没有隐式声明和定义为删除
why the move constructor/move assignment are not implicitly declared and defined as deleted if we only define copy constructor/oper=?
根据C++标准12.8.7:
如果类定义声明了move构造函数或move赋值运算符,隐式声明的复制构造函数为定义为已删除;
和12.8.18
如果类定义声明了移动构造函数或移动赋值运算符,定义了隐式声明的复制赋值运算符已删除;
我想知道,如果我们只定义了复制构造函数或复制赋值运算符,为什么移动构造函数/移动赋值没有隐式声明并定义为已删除(在这种情况下,c++11标准不会生成隐式声明的移动构造函数/移动赋值)?
如果是这种情况,那么使用右值作为构造或组装的源将导致编译错误,而不是返回到副本。
一个不存在的函数(显然)不参与过载解决。被定义为已删除的函数正常参与过载解决;如果选择了它,编译将导致一个错误。
此代码编译:
struct Normal
{
Normal() {}
Normal(const Normal &) {}
};
int main()
{
Normal n(Normal{});
}
当此代码导致错误时:
struct Deleted
{
Deleted() {}
Deleted(const Deleted &) {}
Deleted(Deleted&&) = delete;
};
int main()
{
Deleted d(Deleted{});
}
如果在这种情况下删除了移动构造函数,那么尝试从右值复制初始化将是一个错误-删除的移动构造函数将比复制构造函数更匹配。
通常,如果您没有定义移动语义,您会希望复制初始化为复制,而不是被禁止。为了给出这种行为,move构造函数根本没有声明,因此无论是从左值还是从rvalue复制,复制初始化都使用复制构造函数。(只要复制构造函数通过const
引用获取其参数即可。)
如果出于某种原因,您希望只能从左值复制这种相当奇怪的质量,那么您仍然可以自己删除移动操作。
相关文章:
- 具有自定义构造函数 (C++) 的类型的动态数组分配
- 当类成员参数具有相同的名称时,如何定义构造函数?
- C++定义构造函数使对象成为非 POD
- 请描述一下在 c++ 中在此类中定义构造函数的方式?
- 不为 emplace() 定义构造函数的解决方法
- 已定义构造函数的构造函数无法识别
- 在自定义构造函数中的堆上创建指针
- c++ 17 中结构自动定义构造函数的规则是什么?
- Python 错误:在 SWIG 生成的C++模板化代码模块中没有定义构造函数
- unique_ptr看不到派生类的自定义构造函数
- 两种类型的定义构造函数有什么区别?第一个使用":",第二个用大括号(如函数)定义它
- 为什么一个非平凡的成员需要为同一类中的匿名联合定义构造函数
- 为其成员根据模板基类存在的类定义构造函数
- 如何在派生类上具有默认行为,而不是重新定义构造函数
- 在结构中定义构造函数
- 将从基类继承的构造函数与自定义构造函数混合使用
- 如何在模板类外部定义构造函数
- C 需要使用自定义构造函数的帮助
- 可以联合包含具有用户定义构造函数的类的对象
- 具有用户定义构造函数的非聚合类的值初始化