微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在愚蠢的small_vector

如何解决在愚蠢的small_vector

在研究类似 constexpr 向量的容器的想法时,我遇到了 folly's small_vector container。我正在通读实现,但对 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();
    }

我的理解是:对于未初始化内存的数组部分,它们使用带有 std::move 的新位置。对于之前移动对象的数组部分,它们使用移动分配。

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

解决方法

为什么不在这两种情况下都使用新的展示位置

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

或者他们可能假设或期望赋值在理论上对于某些类型比销毁 + 构造更有效。

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

为什么不在两种情况下都使用移动分配?

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。