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

时间:2019-03-01 22:15:46

标签: c++ vector stl c++17

我有一个名为std::vector的{​​{1}}(在编译时我不知道向量的大小)和一个不可移动的类型args

我想创建一个与args大小相同的向量,以使其等于 NonMoveable

我以后不需要更改向量的大小。我该怎么办?

我不能{NonMovable(args[0], additional_arg), NonMovable(args[1], additional_arg), …, NonMovable(args.back(), additional_arg)},然后reserve(),因为emplace_back()需要移动(以允许重新分配,这在我的情况下是不可能的)

我不想使用emplace_back(),因为它不连续。

2 个答案:

答案 0 :(得分:3)

您可以:

  • 拥有vector<unique_ptr<T>>vector<optional<T>>vector<some_other_defer_storage_mechanism<T>>而不只是vector<T>-这些都是包装器类型,它们添加了一些功能T而不影响{{1 }}(T使其可移动,unique_ptr<T>确保默认构造,因此您可以在optional<T>内以合适的尺寸建造emplace(),依此类推。)
  • 使用optionaldeque<T>不需要移动(尽管您失去了连续性)
  • 编写一个自己的动态数组,该数组大致相当于一个emplace_back,该动态数组只为pair<unique_ptr<T[]>, size_t> n分配空间,然后在每个位置放置新消息,确保销毁它们正确的事。实施起来并不是很糟糕-因为您不会更改大小,因此需要支持非常少量的整体操作。

其中哪一个是最佳答案,实际上取决于。

答案 1 :(得分: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型的,但满足连续性要求。当然,应将其封装在自定义容器中,以允许在销毁容器时自动销毁和取消分配。