← Patterns

Range-based algorithms

12345678910111213141516#include <iterator> #include <utility> template <typename ForwardRange> void algorithm(ForwardRange& range) { using std::begin; using std::end; using iterator = decltype(begin(range)); iterator it_begin = begin(range); iterator it_end = end(range); // Now use it_begin and it_end to implement algorithm }

This pattern is licensed under the CC0 Public Domain Dedication.

Requires c++11 or newer.

Intent

Implement algorithms that can be applied to any generic range of elements.

Description

Note: The existing algorithms in the standard library are not range-based but iterator-based. However, the Ranges Technical Specification is experimenting with introducing ranges and range-based algorithms to the standard, which are more flexible and provide a simpler interface to client code.

Lines 4–16 define a function template representing a range-based algorithm. It takes a single range argument, which is any type that supports begin and end functions that provide iterators to the beginning and end of the range. A range may be classified depending on the iterators that it provides:

For the example code, we assume that the algorithm requires only Forward Iterators, so can be applied to any Forward Range. We therefore name the template parameter ForwardRange on line 4 to illustrate this.

On lines 12–13, we call begin and end on the range to get the respective iterators to the beginning and end of the range. We use using-declarations on lines 7–8 to allow these calls to be found via argument-dependent lookup before using the standard std::begin and std::end functions. With these iterators, we can now implement the algorithm over the elements between them.

If the iterators are not necessary to implement the algorithm, we may instead be able to use a simple range-based for loop.

Contributors

  • Joseph Mansfield

Last Updated

27 August 2018

Source

Fork this pattern on GitHub

Share