Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a reason to use `remove` outside of the erase-remove idiom?

Tags:

c++

stl

As far as the algorithm is concerned, removing a set of element from a contiguous array can be done effectively in two parts.

  1. Move all the elements not to be deleted to the front of the array.
  2. Mark the array smaller.

This can be done in C++ with the erase-remove idiom.

vector<T> v; // v = {0,1,2,3,0,0,7};
vector<T>::iterator it = remove(v.begin(),v.end(),e);
// move all elements not to be deleted to the front
// Yes, remove is not the brightest name for that.
// Especially as list::remove really remove elements from the list.
// now v = {1,2,3,7,?,?,?} results marked in question marks
// are implementation dependent.
v.erase(it,v.end());
// get rid of the elements marked as question marks.
// v = {1,2,3,7}

Now, the content of the elements in the question mark is unknown. The only thing we can do with them is get rid of them (by overwriting them, or by removing them).

Is there a real world situation where you need to use remove without erase? The only situation I could think of is

copy(src.begin(),src.end(),remove(v.begin(),v.end(),e),v.end());

replacing all As with Bs, and requiring that all those new Bs will be contiguous. Doesn't make too much sense.

edit: Does it make sense to anything other than contigious memory container (deque and vector actually)?

If indeed I'm correct, why was it implemented as a standalone algorithm, instead of vector::remove_if, dequeue::remove_if etc.

like image 799
Elazar Leibovich Avatar asked Oct 06 '11 13:10

Elazar Leibovich


People also ask

Why erase remove c++?

The erase–remove idiom is a common C++ technique to eliminate elements that fulfill a certain criterion from a C++ Standard Library container.

How to remove std in c++?

std::remove, std::remove_if in c++ It is defined in <algorithm> library. It removes value from range. Transforms the range [first,last) into a range with all the elements that compare equal to val removed, and returns an iterator to the new end of that range.


1 Answers

Your question goes the wrong way round. Rather, one would ask "why should I implement this identical algorithm repetitively for each container, instead of making it a single, free function"?

The key idea behind separating containers, iterators and algorithms is that you don't have a complexity explosion as you write more algorithms and more containers. If you want to write a new container that has contiguous storage, you can use remove on it right out of the box (provided you supply forward or random-access iterators), without duplicating any code.

The only reason that certain containers implement their own, member versions of algorithms is because either they can do it better than the generic version (e.g. std::set::find vs. std::find; or list::remove), or because they can do what the generic version cannot do (e.g. std::list::sort vs. std::sort). But if you can, you should use the free version for maximal generality and genericity.

like image 103
Kerrek SB Avatar answered Sep 23 '22 06:09

Kerrek SB