为什么无需将具有删除的副本构造函数的类型的移动构造函数标记为已删除? [英] Why is there no need to mark the move constructor of a type with a deleted copy constructor as deleted?
问题描述
考虑 std :: mutex
。我知道为什么 std :: mutex
不能移动。但是它的副本构造函数显然标记为已删除,但是我还没有看到它的move构造函数这样的声明。那么cppreference为什么说 std :: mutex
不能移动?
Consider std::mutex
. I understand why std::mutex
should not be movable. But its copy constructor is clearly marked as deleted, but I have not seen such a declaration for its move constructor. So why does cppreference say std::mutex
is not movable?
根据文档( https://en.cppreference.com/w/cpp/language/move_constructor )有许多无法满足的前提条件会阻止隐式move构造函数。但是我找不到这个问题的原因。对于这个问题,我将不胜感激。
As per the documentation(https://en.cppreference.com/w/cpp/language/move_constructor), there are many preconditions that are not fulfilled that prevent the implicit move constructor. But I could not find the reason for this question. I would be grateful to have some help with this question.
我真的不认为这个问题(en.cppreference.com/w/cpp/thread / mutex /〜mutex)是 std :: mutex
的用户定义的析构函数。
I really don't think this one(en.cppreference.com/w/cpp/thread/mutex/~mutex) is the user-defined destructor for std::mutex
.
推荐答案
编译器未生成隐式move构造函数的原因有两个:
There are two reasons why the implicit move constructor is not generated by the compiler:
-
std :: mutex
可能具有用户定义的析构函数。在某些平台上,互斥对象分配内存,因此析构函数必须清理内存,例如通过调用pthread_mutex_destroy()
。 - 复制构造函数被显式删除,这被视为用户声明的。
std::mutex
might have a user-defined destructor. On some platforms, mutex objects allocate memory, so the destructor has to clean that up, for example by callingpthread_mutex_destroy()
.- The copy constructor is explicitly deleted, which counts as being "user-declared".
那么为什么用这种方式编写标准以上情况阻止了隐式move构造函数的生成?首先考虑一下您没有定义任何构造函数/析构函数/复制/移动运算符的类。然后整个类的行为就像成员变量的集合一样。在构造/销毁/复制/移动这样的集合时,逻辑上要做的就是将操作分别应用于每个项目。但是,一旦用户定义了这些操作,就会在类中添加新的语义,并且基本上,它不再仅仅是成员变量的集合。通过查看用户定义的操作来隐式创建所有其他操作,编译器还不够聪明,因此安全的做法是不要隐式创建它们。
So why is the standard written in such a way that the above cases prevent the generation of an implicit move constructor? First think of a class where you don't have any constructor/destructor/copy/move operator defined. Then the whole class just behaves as a collection of member variables. The logical thing to do when constructing/destructing/copying/moving such a collection is just to apply the operation on each item individually. However, as soon as you user-define on of those operations, you are adding new semantics to your class, and basically it is no longer just a collection of member variables. The compiler isn't smart enough from looking at the operations you user-defined how to implicit create all the other operations, so the safe thing to do is to not implicit create them.
这篇关于为什么无需将具有删除的副本构造函数的类型的移动构造函数标记为已删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!