0

在研究 constexpr 类向量容器的想法时,我遇到了愚蠢的 small_vector 容器。我正在阅读实现,并对以下部分感到困惑moveObjectsRightAndCreate

    for (; in != first && out > lastConstructed;) {
      // Out must be decremented before an exception can be thrown so that
      // the rollback guard knows where to start.
      --out;
      new (out) T(std::move(*(--in)));
    }
    for (; in != first;) {
      --out;
      *out = std::move(*(--in));
    }
    for (; out > lastConstructed;) {
      --out;
      new (out) T(create());
    }
    for (; out != first;) {
      --out;
      *out = create();
    }

我的理解是:对于内存未初始化的数组部分,他们使用placement new with std::move。对于先前从其中移动对象的数组部分,它们使用移动分配。

似乎主要区别在于是否使用移动构造函数或移动赋值,但我不确定我是否理解这些选择的含义。为什么不对这两种情况都使用placement new?为什么不对这两种情况使用移动分配?因为我们知道数组的大小,所以无论如何我们都不会在未初始化的内存上调用析构函数,对吧?

4

1 回答 1

2

为什么不在这两种情况下都使用placement new

可能是因为这不允许他们指定元素的析构函数不会被插入调用(以防容量不增长)。他们似乎没有准确地指定他们的 API,但他们可能认为这是隐含的预期。

或者他们可能假设或期望分配在理论上对于某些类型比破坏+构造更有效。

实际原因是其中之一,还是其他原因,只能由容器的作者来回答。

为什么不对这两种情况使用移动分配?

因为在未初始化的内存上移动分配非平凡类型的行为是未定义的。

于 2021-01-01T04:50:44.540 回答