我想将n
个连续的不可复制元素插入std::vector
中。我调查了insert
和emplace
的签名,发现:
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())
,这是不可接受的。
是否有任何标准且可移植的方式来做到这一点?
答案 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)));
答案 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 Smith的comment,我终于明白了。 我一直在寻找完全错误的东西。毕竟,您必须复制一些内容。您无法多次完善前进:
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
因此,如果类型是不可复制的,则“每个参数都用相同的参数构造”是不可能的。