WEBINAR:
On-Demand
Building the Right Environment to Support AI, Machine Learning and Deep Learning
Instantiaton
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() helper function:
template<class CopyableRange, class Range>
CopyableRange copy_range(const Range& r);
std::range another_range=std::copy_range(results_range);
//copy ctor version:
std::range yet_another_range(another_range);
Finally, creating an empty range is trivial:
std::range empty_range; //fill it later
Accessing a Range
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());
vector::iterator vbeg=range_begin(results_range),
vend=range_end(results_range);