Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are STL algorithms called differently for different classes?

Tags:

c++

list

stl

vector

I am currently looking at STL libraries and am wondering why for a vector class vector<string> names; I have to call remove(); as follows:

names.erase(remove(names.begin(), names.end(), "Simon"), names.end());

While when using a list class list<string> names; I can call the function as follows:

remove("Simon");

I also notice the same for reverse(); for vector<string> names; it is called as follows:

reverse(names.begin(), names.end());

While for list<string> names; it is called as follows:

names.reverse();

Is it more proper to always call the way the vector would? why is this? I'm very new to C++ so I'm keen to know the best way to do things.

like image 721
stuart194 Avatar asked Jan 23 '26 14:01

stuart194


1 Answers

Basically, there are some special cases that have to do with the nature of specific containers.

In general the free functions std::remove, std::remove_if, and std::reverse declared in the <algorithm> header will work on vectors, lists, deques, and arrays by copying and moving elements. (They will not, of course, work on sets or maps, since for those you are not free to rearrange elements willy-nilly.) Note that std::remove does not delete elements from containers.

In general the member function erase of each container type is used to delete elements from that container. (Note that std::array does not have erase because its size is fixed.)

There are special cases:

  • std::list provides reverse, as a member because only the member function can guarantee that it does not invalidate any iterators; the generic std::reverse cannot.
  • The same goes for remove and remove_if though the names are misleading because unlike the free functions, the members do delete elements from the list.
  • There is also a member sort for std::list because the generic std::sort only works on random access iterators.
  • For sets and maps we should use their member lower_bound, upper_bound, equal_range, and count instead of the generic versions, since they know how to walk down the tree and get the result in logarithmic time whereas the free functions will use linear time.

Generally, the principle appears to be: the standard library containers support uniform interfaces as far as possible, but also provide additional specialized functions in order to provide functionality that depends on their internals.

like image 117
Brian Bi Avatar answered Jan 25 '26 03:01

Brian Bi