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 parentheses86

(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} }

where __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:

if _RangeT is an array type,

*begin-expr*and*end-expr*are __range and __range + __bound, respectively, where __bound is the array bound. If _RangeT is an array of unknown size or an array of incomplete type, the program is ill-formed;if _RangeT is a class type, the

*unqualified-ids*begin and end are looked up in the scope of class _RangeT 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 with argument-dependent lookup ([basic.lookup.argdep]). For the purposes of this name lookup, namespace std is an associated namespace.

[ *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.

this ensures that a top-level comma operator cannot be
reinterpreted as a delimiter between *init-declarators* in the
declaration of __range.