[ *Note:* This clause is presented as a set of differences to apply to
ISO/IEC 14882:2014 §[stmt.ranged] to allow differently typed begin and end
iterators, as in C++17. * — end note* ]

For a range-based for statement of the form

`for ( for-range-declaration : expression ) statement`

let range-init be equivalent to the expression surrounded by parentheses

`( expression )`

and for a range-based for statement of the form

`for ( for-range-declaration : braced-init-list ) statement`

let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to

{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) {for-range-declaration= *__begin;statement} }

The range-based for statement

`for ( for-range-declaration : for-range-initializer ) statement`

is equivalent to

{ auto && __range = for-range-initializer; auto __begin = begin-expr; auto __end = end-expr; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }

where

if the for-range-initializer is an expression, it is regarded as if it were surrounded by parentheses (so that a comma operator cannot be reinterpreted as delimiting two init-declarators);

__range, __begin, and __end are variables defined for exposition only; and _RangeT is the type of the expression, and

*begin-expr*and*end-expr*are determined as follows:begin-expr and end-expr are determined as follows:

if _RangeTthe for-range-initializer is an expression of array type R,

*begin-expr*and*end-expr*are __range and __range + __bound, respectively, where __bound is the array bound. If _RangeTR is an array of unknown sizebound or an array of incomplete type, the program is ill-formed;if _RangeTthe for-range-initializer is aan expression of class type C, the unqualified-ids begin and end are looked up in the scope of class _RangeTC as if by class member access lookup ([basic.lookup.classref]), and if either (or both) finds at least one declaration, begin-expr and end-expr are __range.begin() and __range.end(), respectively;

otherwise,

*begin-expr*and*end-expr*are begin(__range) and end(__range), respectively, where begin and end are looked up in the associated namespaces ([basic.lookup.argdep]). [*Note:*Ordinary unqualified lookup ([basic.lookup.unqual]) is not performed.*— end note*]

[ *Example:*

int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2;

In the decl-specifier-seq of a for-range-declaration, each decl-specifier shall be either a type-specifier or constexpr. The decl-specifier-seq shall not define a class or enumeration.