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

时间:2017-07-01 16:54:57

标签: c++ memory move-semantics allocator move-constructor

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

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

2 个答案:

答案 0 :(得分:2)

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

  

(14)非联合类X的隐式定义的复制/移动构造函数   执行其基础和成员的成员复制/移动。 [ 注意:   忽略非静态数据成员的默认成员初始值设定项。   另请参见15.6.2中的示例。 - 尾注]顺序   初始化与base的初始化顺序相同   用户定义的构造函数中的成员(见15.6.2)

按照链接引导我们 第15.6.2节[class.base.init]

  

(13.3)然后,按照它们的顺序初始化非静态数据成员   在类定义中声明(再次无论顺序如何)   mem-initializer s)

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

是合法的。

答案 1 :(得分:0)

  

[basic.types] / 3 对于任何简单的可复制类型T,如果指向T的两个指针指向不同的T个对象{{1} }和obj1,如果组成obj2的基础字节(1.7)被复制到obj1,则obj2obj1都不是基类子对象,obj2随后应保持与obj2相同的值。

因此,对于一个简单的可复制类型,简单地复制字节是安全的,例如与obj1。您可以使用memmove来测试此特征。

请注意,平凡移动可构造是一个必要但不充分的条件,可以轻易复制:

  

[class] / 6 平易可复制的课程是一个课程:

     

(6.1) - 其中每个复制构造函数,移动构造函数,复制赋值运算符和移动赋值运算符(12.8,13.5.3)被删除或无关紧要,

     

(6.2) - 至少有一个未删除的复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符,以及

     

(6.3) - 有一个简单的,未删除的析构函数(12.4)。