默认移动构造函数中的赋值顺序是什么?
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).
我目前正在使用 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 toT
point to distinctT
objectsobj1
andobj2
, where neitherobj1
norobj2
is a base-class subobject, if the underlying bytes (1.7) making upobj1
are copied intoobj2
,obj2
shall subsequently hold the same value asobj1
.
所以对于一个简单的可复制类型,简单地复制字节是安全的,例如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).