默认移动构造函数中的赋值顺序是什么?

What is the order of assignments inside a default move constructor?

我目前正在使用 C++ 编写自定义分配器。该分配器必须通过移动内存和对象来定期对其内存进行碎片整理。这些移位总是向下的,这意味着移动的内存块的地址在移动时总是减少。当旧内存块和新内存块不重叠时这样做没有问题。如果它们重叠,我首先必须将对象移动到分配器内存之外的临时区域,然后将其移回新的内存块。

如果移动类型的 std::is_trivially_move_constructible 为真,那么如果默认移动构造函数中的赋值顺序定义明确,我可能会将此额外移动保存到临时内存块中。这引出了我的问题:分配的顺序是定义明确还是特定于平台?

来自标准(第 15.8.1 节 [class.copy.ctor])

(14) The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. [ Note: Default member initializers of non-static data members are ignored. See also the example in 15.6.2. — end note ] The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see 15.6.2)

遵循 link 将我们带到 第 15.6.2 节 [class.base.init]

(13.3) Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializer s)


没有完全回答这个问题,但正如 Igor Tandetnik 在他的回答中所说,将一个普通的构造函数转换为 std::memmove

是合法的

[basic.types]/3 For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (1.7) making up obj1 are copied into obj2, obj2 shall subsequently hold the same value as obj1.

所以对于一个简单的可复制类型,简单地复制字节是安全的,例如memmove。您可以使用 std::is_trivially_copyable.

测试此特征

请注意平凡移动构造是平凡可复制的必要但不充分条件:

[class]/6 A trivially copyable class is a class:

(6.1) — where each copy constructor, move constructor, copy assignment operator, and move assignment operator (12.8, 13.5.3) is either deleted or trivial,

(6.2) — that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and

(6.3) — that has a trivial, non-deleted destructor (12.4).