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.
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:
- Forward Range - provides Forward Iterators
- Bidirectional Range - provides Bidirectional Iterators
- Random Access Range - provides Random Access Iterators
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.