9 Statements [stmt.stmt]

9.5 Iteration statements [stmt.iter]

9.5.4 The range-based for statement [stmt.ranged]

for Заявление на основе диапазона

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

эквивалентно

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

куда

  • если for-range-initializerесть expression, он рассматривается, как если бы он был заключен в круглые скобки (так что оператор запятой не может быть интерпретирован как разделяющий два init-declarators);

  • _­_­range, _­_­beginи _­_­end - переменные, определенные только для демонстрации; а также

  • begin-expr и end-expr определяются следующим образом:

    • если for-range-initializer- выражение типа массива R, begin-expr и end-expr - _­_­range и _­_­range + _­_­bound, соответственно, где _­_­bound - граница массива. Если R это массив с неизвестной границей или массив неполного типа, программа имеет неправильный формат;

    • если for-range-initializerявляется выражением типа класса C, unqualified-ids begin и end ищутся в области видимости, C как если бы by class member access lookup, и если один из них (или оба) находит по крайней мере одно объявление, begin-expr и end-expr являются _­_­range.begin() и _­_­range.end(), соответственно;

    • в противном случае begin-expr и end-expr являются begin(_­_­range) и end(_­_­range), соответственно, где begin и end ищутся в associated namespaces. [ Note: Обычный unqualified lookup не выполняется. ] end note

[Example:

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

end example]

В decl-specifier-seqa for-range-declarationкаждый decl-specifierдолжен быть либо a, type-specifier либо constexpr. Не decl-specifier-seqдолжен определять класс или перечисление.