我有一个名为std::vector
的args
(我不知道编译时矢量的大小)和一个不可移动的类型NonMoveable
。
我想创建一个与args大小相同的向量,以便它等于{NonMovable(args[0], additional_arg), NonMovable(args[1], additional_arg), …, NonMovable(args.back(), additional_arg)}
我以后不需要改变矢量的大小。我怎么做?
我不能reserve()
然后emplace_back()
因为emplace_back()
需要移动(允许重新分配,这在我的情况下是不可能的)
我不想使用std::list
,因为它不是连续的。
您可以:
vector<unique_ptr<T>>
或vector<optional<T>>
或vector<some_other_defer_storage_mechanism<T>>
而不仅仅是vector<T>
- 这些都是包装类型添加一些功能T
而不影响T
(unique_ptr<T>
使它可移动,optional<T>
确保默认构造,所以你可以构建正确的大小然后emplace()
在optional
等。)deque<T>
,它不需要移动emplace_back
(虽然你失去了Contiguity)pair<unique_ptr<T[]>, size_t>
,它只为n
T
s分配空间,然后将placement-news分配给每个,确保破坏做正确的事情。实现起来并不是那么糟糕 - 因为您不会改变大小,所以需要支持极少量的整体操作。无论哪一个是最好的答案真的取决于。
如果你想要元素是连续的,你可以使用旧的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,但满足了连续的要求。当然,这应该封装在自定义容器中,以允许在容器销毁时自动销毁和解除分配。