如何在元素类型不可复制的std :: vector中插入n个连续元素?

时间:2018-08-13 01:45:28

标签: c++ c++11

我想将n个连续的不可复制元素插入std::vector中。我调查了insertemplace的签名,发现:

iterator insert( const_iterator pos, size_type count, const T& value );

但是,由于无法复制T,因此此重载无济于事。我还看到了:

template< class... Args > 
iterator emplace( const_iterator pos, Args&&... args );

emplace解决了不可复制的问题,但是每次只能插入一个元素。由于我要插入n元素,因此总体时间复杂度是二次O(n*size()),这是不可接受的。

是否有任何标准且可移植的方式来做到这一点?

3 个答案:

答案 0 :(得分:3)

如果要在n的末尾插入vector默认构造的元素,则可以使用resize

std::vector<std::unique_ptr<int>> v;
v.resize(v.size() + 10);              // append 10 elements

如果要将它们插入其他位置,请使用insert重载,该重载需要一对迭代器;在临时数组中构造元素并将其移至vector

std::unique_ptr<int> arr[10];
v.insert(v.begin(),
         std::make_move_iterator(std::begin(arr)),
         std::make_move_iterator(std::end(arr)));

Live demo

答案 1 :(得分:1)

将它们放在预留位置的末尾。对于m个新元素和n个现有元素,O(n + m)。

std::rotate将它们移到您想要的位置。 O(m + n-k),其中k是您想要它们在向量中的位置。


或者编写一个生成输入的迭代器来生成有问题的元素。然后使用template< class InputIt > iterator insert( const_iterator pos, InputIt first, InputIt last );重载。这样具有更多样板,但避免了一些移动。

答案 2 :(得分:0)

半年后重读Ross Smithcomment,我终于明白了。 我一直在寻找完全错误的东西。毕竟,您必须复制一些内容。您无法多次完善前进:

template <typename T>
void f(T&& x)
{
    g(std::forward<T>(x)); // ok
    h(std::forward<T>(x)); // oops -- x may be in an invalid state
}

f(std::vector<int>{1, 2, 3}); // oops -- when h() is called,
                              // the vector is possibly already empty

因此,如果类型是不可复制的,则“每个参数都用相同的参数构造”是不可能的。