[stmt.iter]
8 Statements [stmt]
8.6 Iteration statements [stmt.iter]
8.6.1 General [stmt.iter.general]
8.6.2 The while statement [stmt.while]
8.6.3 The do statement [stmt.do]
8.6.4 The for statement [stmt.for]
8.6.5 The range-based for statement [stmt.ranged]
8.6.1 General [stmt.iter.general]
Iteration statements specify looping.
The substatement in an iteration-statement implicitly defines a block scope which is entered and exited each time through the loop.
If the substatement in an iteration-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original statement.
A trivial infinite loop is a trivially empty iteration statement for which the converted controlling expression is a constant expression, when interpreted as a constant-expression ([expr.const]), and evaluates to true.
The statement of a trivial infinite loop is replaced with a call to the function std::this_thread::yield ([thread.thread.this]); it is implementation-defined whether this replacement occurs on freestanding implementations.
8.6.2 The while statement [stmt.while]
In the while statement, the substatement is executed repeatedly until the value of the condition ([stmt.pre]) becomes false.
The test takes place before each execution of the substatement.
A while statement is equivalent to
[Note 1:
The variable created in the condition is destroyed and created with each iteration of the loop.
[Example 1: struct A { int val; A(int i) : val(i) { } ~A() { } operator bool() { return val != 0; } }; int i = 1; while (A a = i) { i = 0; }
In the while-loop, the constructor and destructor are each called twice, once for the condition that succeeds and once for the condition that fails.
— end example]
— end note]
8.6.3 The do statement [stmt.do]
In the do statement, the substatement is executed repeatedly until the value of the expression becomes false.
The test takes place after each execution of the statement.
8.6.4 The for statement [stmt.for]
[Note 1:
Thus the first statement specifies initialization for the loop; the condition ([stmt.pre]) specifies a test, sequenced before each iteration, such that the loop is exited when the condition becomes false; the expression often specifies incrementing that is sequenced after each iteration.
— end note]
8.6.5 The range-based for statement [stmt.ranged]
The range-based for statement
is equivalent to
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
- begin-expr and end-expr are determined as follows:
if the type of range is a reference to an array type R, begin-expr and end-expr are range and range + N, respectively, where N is the array bound.
If R is an array of unknown bound or an array of incomplete type, the program is ill-formed;
if the type of range is a reference to a class type C, and searches in the scope of C ([class.member.lookup]) for the names begin and end each find 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 undergo argument-dependent lookup ([basic.lookup.argdep]).
[Example 1: int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2; — end example]
[Example 2: using T = std::list<int>; const T& f1(const T& t) { return t; } const T& f2(T t) { return t; } T g(); void foo() { for (auto e : f1(g())) {} for (auto e : f2(g())) {} } — end example]