From Jason Turner

[stmt.ranged]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpjv20dq9k/{from.md → to.md} +28 -9
tmp/tmpjv20dq9k/{from.md → to.md} RENAMED
@@ -26,25 +26,24 @@ where
26
  - if the *for-range-initializer* is an *expression*, it is regarded as
27
  if it were surrounded by parentheses (so that a comma operator cannot
28
  be reinterpreted as delimiting two *init-declarator*s);
29
  - *`range`*, *`begin`*, and *`end`* are variables defined for exposition
30
  only; and
31
- - *begin-expr* and *end-expr* are determined as follows:
32
  - if the *for-range-initializer* is an expression of array type `R`,
33
- *begin-expr* and *end-expr* are *`range`* and *`range`* `+` `N`,
34
  respectively, where `N` is the array bound. If `R` is an array of
35
  unknown bound or an array of incomplete type, the program is
36
  ill-formed;
37
  - if the *for-range-initializer* is an expression of class type `C`,
38
- the *unqualified-id*s `begin` and `end` are looked up in the scope
39
- of `C` as if by class member access lookup
40
- [[basic.lookup.classref]], and if both find at least one
41
- declaration, *begin-expr* and *end-expr* are `range.begin()` and
42
  `range.end()`, respectively;
43
- - otherwise, *begin-expr* and *end-expr* are `begin(range)` and
44
- `end(range)`, respectively, where `begin` and `end` are looked up in
45
- the associated namespaces [[basic.lookup.argdep]].
46
  \[*Note 1*: Ordinary unqualified lookup [[basic.lookup.unqual]] is
47
  not performed. — *end note*]
48
 
49
  [*Example 1*:
50
 
@@ -54,9 +53,29 @@ for (int& x : array)
54
  x *= 2;
55
  ```
56
 
57
  — *end example*]
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  In the *decl-specifier-seq* of a *for-range-declaration*, each
60
  *decl-specifier* shall be either a *type-specifier* or `constexpr`. The
61
  *decl-specifier-seq* shall not define a class or enumeration.
62
 
 
26
  - if the *for-range-initializer* is an *expression*, it is regarded as
27
  if it were surrounded by parentheses (so that a comma operator cannot
28
  be reinterpreted as delimiting two *init-declarator*s);
29
  - *`range`*, *`begin`*, and *`end`* are variables defined for exposition
30
  only; and
31
+ - *`begin-expr`* and *`end-expr`* are determined as follows:
32
  - if the *for-range-initializer* is an expression of array type `R`,
33
+ *`begin-expr`* and *`end-expr`* are *`range`* and *`range`* `+` `N`,
34
  respectively, where `N` is the array bound. If `R` is an array of
35
  unknown bound or an array of incomplete type, the program is
36
  ill-formed;
37
  - if the *for-range-initializer* is an expression of class type `C`,
38
+ and searches in the scope of `C` [[class.member.lookup]] for the
39
+ names `begin` and `end` each find at least one declaration,
40
+ *`begin-expr`* and *`end-expr`* are `range.begin()` and
 
41
  `range.end()`, respectively;
42
+ - otherwise, *`begin-expr`* and *`end-expr`* are `begin(range)` and
43
+ `end(range)`, respectively, where `begin` and `end` undergo
44
+ argument-dependent lookup [[basic.lookup.argdep]].
45
  \[*Note 1*: Ordinary unqualified lookup [[basic.lookup.unqual]] is
46
  not performed. — *end note*]
47
 
48
  [*Example 1*:
49
 
 
53
  x *= 2;
54
  ```
55
 
56
  — *end example*]
57
 
58
+ [*Note 2*: The lifetime of some temporaries in the
59
+ *for-range-initializer* is extended to cover the entire loop
60
+ [[class.temporary]]. — *end note*]
61
+
62
+ [*Example 2*:
63
+
64
+ ``` cpp
65
+ using T = std::list<int>;
66
+ const T& f1(const T& t) { return t; }
67
+ const T& f2(T t) { return t; }
68
+ T g();
69
+
70
+ void foo() {
71
+ for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended
72
+ for (auto e : f2(g())) {} // undefined behavior
73
+ }
74
+ ```
75
+
76
+ — *end example*]
77
+
78
  In the *decl-specifier-seq* of a *for-range-declaration*, each
79
  *decl-specifier* shall be either a *type-specifier* or `constexpr`. The
80
  *decl-specifier-seq* shall not define a class or enumeration.
81