// the simple form
for (range-declaration : range-expression)
// which expands to
auto && __range = range-expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end;
++__begin) {
range-declaration = *__begin;
loop-statement
}
The range-expression
is where the magic happens. It needs to be
- An array with a known size:
begin_expr
is__range
andend_expr
is(__range + bound)
. - a class type with a member named
begin()
(__range.begin()
) and a memberend()
(__range.end()
). - By Koenig lookup to find a pair of free functions of
begin(__range)
andend(__range)=
.Thus, the following implementation from Windows Implementation Library is totally valid.
template <typename T>
class pointer_range
{
public:
pointer_range(T begin_, T end_) : m_begin(begin_), m_end(end_) {}
T begin() const { return m_begin; }
T end() const { return m_end; }
private:
T m_begin;
T m_end;
};
And the following use runs fine.
int main() {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
for (int i : pointer_range<int*>(&a[0], &a[10])) {
std::cout << i << ' ';
}
std::cout << '\n';
}