Let's say I have a vector(v1) of size 10. Now I want to only keep parts of the elements, using:
v1.assign(v1.begin() + 2, v1.begin() + 6);
What I'm not sure is, whether the original elements will be destroyed before assignment. If they are destoyed first, then I cannot rely on the original data.
This page seems to indicate that elements are erased first. However, a quick experiment tells me that the data are correctly assigned to itself.
So what is happening when assigning part of a vector to itself ?
Per the C++14 standard Table 100 — Sequence container requirements (in addition to container)
The expression a.assign(i,j)
has a pre-condition that i
and j
are not iterators into a. Since
v1.assign(v1.begin() + 2, v1.begin() + 6);
Uses iterators that are iterators into v1
so you have violated that pre-condition
If you want to reset the vector to contain a subrange then you can copy those elements into a temporary vector and then assign that temporary vector back to main vector. This should be a move operation(C++11 and above) so no additional copies are made.
v = std::vector<decltype(v)::value_type>(v.begin() + 2, v.begin() + 6);
As pointed out in the comments from Benjamin Lindley and Barry we can use std::copy
and move iterators like
std::copy(std::make_move_iterator(v.begin() + 2), std::make_move_iterator(v.begin() + 6),
std::make_move_iterator(v.begin()));
From the C++11 Standard:
23.3.6.2 vector constructors, copy, and assignment
template <class InputIterator> void assign(InputIterator first, InputIterator last);
11 Effects:
erase(begin(), end()); insert(begin(), first, last);
In other words, don't use:
v1.assign(v1.begin() + 2, v1.begin() + 6);
By the time insert
is called, first
will be an invalid iterator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With