84 lines
3.5 KiB
Markdown
84 lines
3.5 KiB
Markdown
[stmt.ranged]
|
||
|
||
# 8 Statements [[stmt]](./#stmt)
|
||
|
||
## 8.6 Iteration statements [[stmt.iter]](stmt.iter#stmt.ranged)
|
||
|
||
### 8.6.5 The range-based for statement [stmt.ranged]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L703)
|
||
|
||
The range-based for statement
|
||
|
||
for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") : [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
|
||
is equivalent to
|
||
|
||
{
|
||
[*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt
|
||
auto &&*range* = [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ;
|
||
auto *begin* = *begin-expr* ;
|
||
auto *end* = *end-expr* ;
|
||
for ( ; *begin* != *end*; ++*begin* ) {
|
||
[*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") = * *begin* ;
|
||
[*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
}
|
||
}
|
||
|
||
where
|
||
|
||
- [(1.1)](#1.1)
|
||
|
||
if the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]"),
|
||
it is regarded as if it were surrounded by parentheses (so that a comma operator
|
||
cannot be reinterpreted as delimiting two [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]")*s*);
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
*range*, *begin*, and *end* are variables defined for
|
||
exposition only; and
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
*begin-expr* and *end-expr* are determined as follows:
|
||
* [(1.3.1)](#1.3.1)
|
||
|
||
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[.](#1.3.1.sentence-1)
|
||
If R is an array of unknown bound or an array of
|
||
incomplete type, the program is ill-formed;
|
||
|
||
* [(1.3.2)](#1.3.2)
|
||
|
||
if the type of *range* is a reference to a
|
||
class type C, and
|
||
searches in the scope of C ([[class.member.lookup]](class.member.lookup "6.5.2 Member name 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;
|
||
|
||
* [(1.3.3)](#1.3.3)
|
||
|
||
otherwise, *begin-expr* and *end-expr* arebegin(*range*) and end(*range*), respectively,
|
||
where begin and end undergo
|
||
argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#1.3.3.sentence-1)
|
||
[*Note [1](#note-1)*:
|
||
Ordinary unqualified lookup ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup")) is not
|
||
performed[.](#1.3.3.sentence-2)
|
||
â *end note*]
|
||
|
||
[*Example [1](#example-1)*: int array[5] = { 1, 2, 3, 4, 5 };for (int& x : array) x *= 2; â *end example*]
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
The lifetime of some temporaries in the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is extended to cover the entire loop ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#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())) {} // OK, lifetime of return value of g() extendedfor (auto e : f2(g())) {} // undefined behavior} â *end example*]
|