std::remove

Dec 27, 2014 at 12:10pm
Hey,

Apparently, the way std::remove( in <algorithm> ) works is that it pushed the unwanted elements to the front and changes the end() iterator position. I tried
to see the removed elements and i succeeded with an overflow. Why do you think the implemented it that way ? why didn't the implement std::remove in such a way that it invalidates the iterators after the removal ?
Dec 27, 2014 at 12:12pm
why didn't the implement std::remove in such a way that it invalidates the iterators after the removal ?
wat?
Dec 27, 2014 at 1:11pm
std::remove can't change the size of a container. not all containers can change their size, array for example. If you need to actually delete something from the container, and the container has the ability to do that. Then you can use the remove erase idiom.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <algorithm>
#include <vector>

int main()
{
	std::vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, };

	vec.erase(std::remove(vec.begin(), vec.end(), 1), vec.end());

	for (auto element : vec)
		std::cout << element;

	std::cin.ignore();
	return 0;
}
Last edited on Dec 27, 2014 at 1:19pm
Dec 27, 2014 at 1:37pm
Apparently, the way std::remove( in <algorithm> ) works is that it pushed the unwanted elements to the front
It moves valid elements to the front and returns new (logical) end.
As Yanson said, remove operattes on iterators, which does not store information about container and methods and avaliability of erasing, so this part you should do manually.
Elements "after the new end" are in unspecified state, it is not guaranteed to be elemnts removed: http://coliru.stacked-crooked.com/a/b344e47b2d50d214 (modified Yanson example). For more complex classes those extra elements usually moved-from and therefore unusable (only thing you can safely do with them is to destroy or assign new value)
Dec 27, 2014 at 1:45pm
> why didn't the implement std::remove in such a way that it invalidates the iterators after the removal ?

Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values.

A call to remove is typically followed by a call to a container's erase method.

- http://en.cppreference.com/w/cpp/algorithm/remove


Erase-remove idiom: https://en.wikipedia.org/wiki/Erase-remove_idiom

To partition the elements of a sequence without invalidating any of them , use std::partition() http://en.cppreference.com/w/cpp/algorithm/partition
Last edited on Dec 27, 2014 at 1:49pm
Dec 27, 2014 at 3:29pm
Thanks guys, every one of your answers taught me something new.
Topic archived. No new replies allowed.