17.2. Basic Model

One of the primary goals of the STL is avoiding repetition & using regular, compact syntax. The STL achieves these goals using separation of concerns.

STL basic model

Algorithms and containers interact through iterators.

17.2.1. Basic Model in Action: find()

Let’s suppose we need to find the first element in a container that equals a value. Specifically, we want to find a specific int in a vector.

This seems like a function we will need to use frequently, so we decide right away that it should be written as a free function:

We could choose to pass an entire container of a specific type to our find function.

std::vector<int>::iterator 
find(std::vector<int>& v, int x) {

and loop over the entire container:

for(auto p = v.begin(); p != v.end(); ++p) {
  if (x == *p) return p;
}

See this example running step-by-step

While this seems easier at first, this version is not nearly as generic, or general purpose as a version that defines a generic type and uses iterators.

  • No way to run this function over part of a container.

  • Need a different function for every container type.

How do we refactor our find function to satisfy our goals?

  • Replace vector<int> v with a pair of iterators

  • Make the iterators generic types

  • Make the value type generic

#include <vector>

// function to find 'x' between first and last
template<class InputIt, class T>
// requires: InputIt is Convertible to T when dereferenced
//        && InputIt is EqualityComparable
//        && T is Regular
InputIt my_find(InputIt first, InputIt last, const T& value)
{
  for (; first != last; ++first) {
    if (*first == value) {
      return first;

And we can prove to ourselves that we get the same results as find.

And since it is arguably the same function as std::find, we now know we no longer need it.

Try this!

Change the name of the function my_find to find and change the matching name on line 24.

Does this program still compile? Explain.

Rewrite the previous example to use find.


More to Explore