按照C++标准12.8.7:
如果类定义声明了移动构造函数或移动赋值操作符,则隐式声明的复制构造函数被定义为已删除;
和12.8.18
如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制赋值操作符被定义为已删除;
我想知道为什么移动构造函数/移动分配没有被隐式声明和定义为已删除(在本例中,c++11标准不会生成隐式声明的移动构造函数/移动分配),如果我们只定义了复制构造函数或复制赋值操作符?
发布于 2015-02-16 16:13:47
如果是这样的话,那么使用rvalue作为构造或评估的来源将导致编译错误,而不是返回到副本。
不存在(显然)的函数不参与过载解析。定义为已删除的函数通常会参与过载解析;如果选择它,则编译将导致错误。
这个代码编撰
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{});
}发布于 2015-02-16 16:17:03
如果在这种情况下删除了移动构造函数,那么尝试从rvalue复制-初始化将是一个错误-被删除的移动构造函数将比复制构造函数更匹配。
通常,如果您没有定义移动语义,您希望复制初始化,而不是不允许复制。为了提供这种行为,根本没有声明移动构造函数,因此复制初始化使用复制构造函数,无论是从lvalue还是rvalue复制。(只要复制构造函数通过const引用获取其参数。)
您仍然可以自己删除移动操作,如果出于某种原因,您希望只从lvalue中获得可复制的相当奇怪的质量。
https://stackoverflow.com/questions/28545644
复制相似问题