To enable a custom type to be used in range-based for loops, you need to do the following:
- Create mutable and constant iterators for the type that must implement the following operators:
- operator++ for incrementing the iterator.
- operator* for dereferencing the iterator and accessing the actual element pointed by the iterator.
- operator!= for comparing with another iterator for inequality.
- Provide free begin() and end() functions for the type.
Given the earlier example of a simple range, we need to provide the following:
- The following minimal implementation of an iterator class:
template <typename T, typename C, size_t const Size>
class dummy_array_iterator_type
{
public:
dummy_array_iterator_type(C& collection,
size_t const index) :
index(index), collection(collection)
{ }
bool operator!= (dummy_array_iterator_type const & other) const
{
return index != other.index;
}
T const & operator* () const
{
return collection.GetAt(index);
}
dummy_array_iterator_type const & operator++ ()
{
++index;
return *this;
}
private:
size_t index;
C& collection;
};
- Alias templates for mutable and constant iterators:
template <typename T, size_t const Size>
using dummy_array_iterator =
dummy_array_iterator_type<
T, dummy_array<T, Size>, Size>;
template <typename T, size_t const Size>
using dummy_array_const_iterator =
dummy_array_iterator_type<
T, dummy_array<T, Size> const, Size>;
- Free begin() and end() functions that return the corresponding begin and end iterators, with overloads for both alias templates:
template <typename T, size_t const Size>
inline dummy_array_iterator<T, Size> begin(
dummy_array<T, Size>& collection)
{
return dummy_array_iterator<T, Size>(collection, 0);
}
template <typename T, size_t const Size>
inline dummy_array_iterator<T, Size> end(
dummy_array<T, Size>& collection)
{
return dummy_array_iterator<T, Size>(
collection, collection.GetSize());
}
template <typename T, size_t const Size>
inline dummy_array_const_iterator<T, Size> begin(
dummy_array<T, Size> const & collection)
{
return dummy_array_const_iterator<T, Size>(
collection, 0);
}
template <typename T, size_t const Size>
inline dummy_array_const_iterator<T, Size> end(
dummy_array<T, Size> const & collection)
{
return dummy_array_const_iterator<T, Size>(
collection, collection.GetSize());
}