Bounds checking is a major problem with built-in arrays. It's also one of the biggest code safety threats. The main cause of array-related bugs is that an array's name decays into a pointer. That pointer tells you only where the array begins, but not where it ends. It's so easy to lose track of the array's end and when that happens, all hell breaks loose. Ranges eliminate this potential bug as they combine the beginning and the end of the array into a single range object. Overloads of range_begin()
generate iterators from a built-in array automatically:
std::range arr_range(range_begin(arr), range_end(arr));
How does it work? The arguments of range_begin()
is "reference to an array of N
elements of type T
template< class T, size_t N >T* range_begin( T(&arr)[N]);
This function returns arr
, the address of the first element, which makes a perfect iterator (recall that built-in arrays are valid STL sequences). The end of this sequence is obtained by calling:
template< class T, size_t N > T* range_end( T(&arr)[N]);
which returns arr+N
STL algorithms that take pairs of iterators will be augmented with corresponding overloads that take ranges instead. In the meantime, you can use ranges even with traditional C++03 algorithms. For example, the find() algorithm locates a certain value within an array of integers like this:
int* p=find(arr_range.begin(), arr_range.end(),999);
Indeed, this version doesn't look simpler than the traditional iterator-based version. However, it's much safer since the use of ranges prevents the inadvertent creation of an invalid iterator.
When range-based versions of Standard Library algorithms become available, the previous find() call will change to:
int* p=find(arr_range, 999);
Which is both safer and syntactically simpler.
With respect to performance, the range library introduces a new class called std::sub_range<Iterator> which encapsulates the notion of a range within another range. sub_range is particularly useful in implementing efficient string manipulation algorithms. A string is represented as a range, and the substring being modified is represented as a sub_range thereof.