C++11C++14C++17Learn C++

Traversing sequences without writing explicit loops

The posts General Loop Statements in Modern C++ and Range-for-statement in modern C++ cover ways to write explicit loops. But explicit loops can be tedious to write and, what is more important, – harder to read, because the resulting code requires to spend the extra time by others in order to understand what is going on in the explicit loop. As alternative, the C++ standard library provides algorithms (defined in <algorithm>) that takes a callback function as an argument to be called for each element of a sequence. But what the advantage of using standard algorithms instead of writing the explicit loops? The main advantage is that it saves the time of both authors and users of the code, because the algorithms provided by the C++ standard library are proven, well-designed, documented and commonly known which allow to express the intentions of the programmers clearly. As a rule, the more standard library facilities are used to write code, the easier it is to maintain that code in the future.

The most general and simple algorithm intended to traverse sequences is std::for_each. This algorithm just eliminate the need to write the explicit loop, for example:

The example above demonstrates how to modify the entire vector of integers, and print the result to the standard output without writing the loops explicitly. Iterators were used to specify the sequence. Although it seems like it looks good, this snippet can be improved. Actually, the function negate() transforms the vector of integers by negating each element. The C++ standard library provides the special algorithm std::transform and unary function object std::negate (defined in <functional>). std::transform applies the given function to each element of the input sequence and stores the returned value to the corresponding element of the output sequence. std::negate<T> just calls operator - (minus) on an instance of type T and returns the result. Hence, the example above could be rewritten as follow:

Looks more clear, isn’t it? The intention to transform the elements of the vector by negating each element is clearly expressed now.

Summarizing this post:

  • in many cases explicit loops can be avoided;
  • std::for_each algorithm is a good alternative to the explicit loops;
  • as a rule of thumb, before using std::for_each with a home-brewed callback, consider if there is a more specialized algorithm and standard helper function which are allows to express the intention more clearly and save you and the reader of your code from extra efforts.

And thanks to the algorithms of the C++ standard library which eliminates the need to write the loops explicitly in many cases!


Oh hi there 👋
It’s nice to meet you.

Sign up to receive awesome C++ content in your inbox, every day.

We don’t spam! Read our privacy policy for more info.

Related posts
C++C++11C++14C++17Introduction to C++Learn C++

Discover Function Overloading in C++

C++Learn C++Videos

Learn C++ With Back to Basics: Move Semantics by David Olsen (CPPCon 2020) Video

C++Introduction to C++Learn C++

Learn to Use Pointers and Memory Address of a Variable in C++

C++Introduction to C++Learn C++

Discover Goto and Labels in C++