I can’t figure out why they have separated algorithms, iterators and containers in C++ STL. If it’s a heavy use of templates everywhere, then we can have classes having all stuff in one place with template parameters.
Some text that I got explains that iterators helps algorithms to interact with containers data but what if containers expose some mechanism to access the data it possesses?
With
Mcontainers +Nalgorithms, one would normally needM * Npieces of code, but with iterators acting as “glue”, this can be reduced toM + Npieces of code.Example: run 2 algorithms on 3 containers
You are calling only 2 different algorithms, and only have code for 3 containers. Each container passes the
begin()andend()iterators to the container. Even though you have3 * 2lines of code to generate the answers, there are only3 + 2pieces of functionality that need to be written.For more containers and algorithms, this separation is an enormous reduction in the combinatorial explosion in code that would otherwise ensue: there are 5 sequence containers, 8 associative containers and 3 container adapters in the STL, and there are almost 80 algorithms in
<algorithm>alone (not even counting those in<numeric>) so that you have only16 + 80instead of16 * 80, an 13-fold reduction in code! (Of course, not every algorithm makes sense on every container, but the point should be clear).The iterators can be divided into 5 categories (input, output, forward, bidirectional and random access), and some algorithms will delegate to specialized versions depending on the iterator capabilities. This will diminish the code reduction somewhat, but greatly improve efficiency by selecting the best adapted algorithm to the iterator at hand.
Note that the STL is not completely consistent in the separation:
std::listhas its ownsortmember function that uses implementation specific details to sort itself, andstd::stringhas an enormous number of member function algorithms, most of which could have been implemented as non-member functions.