创建不可移动类型的std :: vector

问题描述 投票:1回答:2

我有一个名为std::vectorargs(我不知道编译时矢量的大小)和一个不可移动的类型NonMoveable

我想创建一个与args大小相同的向量,以便它等于{NonMovable(args[0], additional_arg), NonMovable(args[1], additional_arg), …, NonMovable(args.back(), additional_arg)}

我以后不需要改变矢量的大小。我怎么做?

我不能reserve()然后emplace_back()因为emplace_back()需要移动(允许重新分配,这在我的情况下是不可能的)

我不想使用std::list,因为它不是连续的。

c++ vector stl c++17
2个回答
3
投票

您可以:

  • 有一个vector<unique_ptr<T>>vector<optional<T>>vector<some_other_defer_storage_mechanism<T>>而不仅仅是vector<T> - 这些都是包装类型添加一些功能T而不影响Tunique_ptr<T>使它可移动,optional<T>确保默认构造,所以你可以构建正确的大小然后emplace()optional等。)
  • 使用deque<T>,它不需要移动emplace_back(虽然你失去了Contiguity)
  • 编写自己的动态数组,大致相当于pair<unique_ptr<T[]>, size_t>,它只为n Ts分配空间,然后将placement-news分配给每个,确保破坏做正确的事情。实现起来并不是那么糟糕 - 因为您不会改变大小,所以需要支持极少量的整体操作。

无论哪一个是最好的答案真的取决于。


1
投票

如果你想要元素是连续的,你可以使用旧的2倍动态数组结构:

// allocate a dynamic array
NonMoveable *mv = std::allocator<NonMoveable>().allocate(args.size());

// use inplace new to construct the NonMoveable elements
for (unsigned int i = 0; i < args.size(); i++) {
    new(mv + i) NonMoveable(args[i], additional_arg);
}

...  // use the dynamic array

// Explicitely delete the elements
for (unsigned int i = 0; i < args.size(); i++) {
    mv[i].~NonMoveable();
}

// and de-allocate
std::allocator<NonMoveable>().deallocate(mv, args.size());

它更像是C-ish,但满足了连续的要求。当然,这应该封装在自定义容器中,以允许在容器销毁时自动销毁和解除分配。

© www.soinside.com 2019 - 2024. All rights reserved.