std::vector<int> v{ 1, 2, 3 };
v.pop_back(); // v becomes {1, 2}
std::vector<int> v{ 1, 2, 3 };
v.clear(); // v becomes an empty vector
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 3); // v becomes {1, 2, 3, 5, 6}
Note: For a vector
deleting an element which is not the last element, all elements beyond the deleted element have to be copied or moved to fill the gap, see the note below and std::list.
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 1, v.begin() + 5); // v becomes {1, 6}
Note: The above methods do not change the capacity of the vector, only the size. See Vector Size and Capacity.
The erase
method, which removes a range of elements, is often used as a part of the erase-remove idiom. That is, first std::remove
moves some elements to the end of the vector, and then erase
chops them off. This is a relatively inefficient operation for any indices less than the last index of the vector because all elements after the erased segments must be relocated to new positions. For speed critical applications that require efficient removal of arbitrary elements in a container, see std::list.
std::vector<int> v{ 1, 1, 2, 2, 3, 3 };
int value_to_remove = 2;
v.erase(std::remove(v.begin(), v.end(), value_to_remove), v.end()); // v becomes {1, 1, 3, 3}
// std::remove_if needs a function, that takes a vector element as argument and returns true,
// if the element shall be removed
bool _predicate(const int& element) {
return (element > 3); // This will cause all elements to be deleted that are larger than 3
}
...
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(), _predicate), v.end()); // v becomes {1, 2, 3}
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(),
[](auto& element){return element > 3;} ), v.end()
);
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
std::vector<int>::iterator it = v.begin();
while (it != v.end()) {
if (condition)
it = v.erase(it); // after erasing, 'it' will be set to the next element in v
else
++it; // manually set 'it' to the next element in v
}
While it is important not to increment it
in case of a deletion, you should consider using a different method when then erasing repeatedly in a loop. Consider remove_if
for a more efficient way.
std::vector<int> v{ -1, 0, 1, 2, 3, 4, 5, 6 };
typedef std::vector<int>::reverse_iterator rev_itr;
rev_itr it = v.rbegin();
while (it != v.rend()) { // after the loop only '0' will be in v
int value = *it;
if (value) {
++it;
// See explanation below for the following line.
it = rev_itr(v.erase(it.base()));
} else
++it;
}
Note some points for the preceding loop:
Given a reverse iterator it
pointing to some element, the method base
gives the regular (non-reverse) iterator pointing to the same element.
vector::erase(iterator)
erases the element pointed to by an iterator, and returns an iterator to the element that followed the given element.
reverse_iterator::reverse_iterator(iterator)
constructs a reverse iterator from an iterator.
Put altogether, the line it = rev_itr(v.erase(it.base()))
says: take the reverse iterator it
, have v
erase the element pointed by its regular iterator; take the resulting iterator, construct a reverse iterator from it, and assign it to the reverse iterator it
.
Deleting all elements using v.clear()
does not free up memory (capacity()
of the vector remains unchanged). To reclaim space, use:
std::vector<int>().swap(v);
shrink_to_fit()
frees up unused vector capacity:
v.shrink_to_fit();
The shrink_to_fit
does not guarantee to really reclaim space, but most current implementations do.