You can construct a range from a pair of iterators, by copying an existing range object or by default constructing an empty range whose iterators are singular
. A singular iterator is similar to a NULL
pointer; the only safe operation that you can perform on a singular iterator is assigning a new value to it.
| Author's Note: There are currently two range libraries. The Boost range library is ready for immediate download and use with any existing C++ compiler. However, this 10 Minute Solution will exclusively use the range library that is currently being incorporated into the C++09 standard. The differences between these two libraries aren't great anyway. I prefer the standard version because that's what most C++ users will have at their disposal in the near future.
The range classes and functions are declared in the augmented standard header <iterator>. All range functions are preceded by range_ to make them distinct from the traditional iterator-based functions. A complete list of the range library functions is available in the official C++09 proposal. For the sake of brevity, I will show only a few illustrative examples here.
The range_make() helper function creates a range from a pair of iterators:
std::vector <double> results;
//...populate the vector
std::range results_range=std::make_range(myvec.begin(), myvec.end());
To copy a range object you can use a copy constructor as usual, or the copy_range()
template<class CopyableRange, class Range>
CopyableRange copy_range(const Range& r);
//copy ctor version:
Finally, creating an empty range is trivial:
Accessing a Range
std::range empty_range; //fill it later
The range library defines functions for accessing a range's iterators and modifying them. In addition, it includes a set of overloaded operators such as ==, !=
for comparing ranges and sub-ranges.
The beginning of a range is equivalent to the first of the two iterators of a range. To extract that iterator, use range_begin(). Notice that this function assumes two other C++09 proposals, namely rvalue-references, and auto and decltype:.
template< class Range > auto range_begin( Range&& r ) -> decltype( r.begin() );
This C++09 syntax is a bit unfamiliar yet but the meaning is self-evident: range_begin()
takes an rvalue reference to a range object r
(recall that Range
in this context is a template parameter). It returns an object whose type is that of the expression r.begin()
. In simpler words, it returns an iterator that designates the beginning of the range.
In a similar vein, call range_end() to extract the end of the range:
template< class Range > auto range_end( Range&& r ) -> decltype( r.end());