Document number: | N2930=09-0120 |
Date: | 2009-07-16 |
Project: | Programming Language C++, Library Working Group |
Reply-to: | Douglas Gregor <doug.gregor at gmail.com> Beman Dawes <bdawes at acm.org> |
Introduction
Summary of proposed changes
Proposed wording
Acknowledgements
With the removal of concepts from the C++0x working paper, the range-based for loop requires new wording that does not rely on concepts. This proposal provides such wording. It also addresses CD1 comments UK 78 and UK 79, whih essentially ask that the range-based for statement "just work" for arrays (without requiring the user to include a header), e.g.,
[ Example:
int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2;—end example ]
begin
and end
(which always includes those begin
and end
functions in namespace std
) to provide the
iterator to the beginning and ending of the sequence.<iterator>
.<initializer_list>
so that it as no dependencies on
other headers and includes no other headers.#include <initializer_list>
.The wording here is based on the current working paper once the concepts proposals and previous range-based for loop (N2778) have been removed. The first two sections have an editorial note that specifies that the text of the current working paper and the net result of removing those previous proposals will be the same. Text to be removed is shown in red, text to be added is shown in green. Underbars are not shown for additions because the many underscores in the affected text become unreadable.
Modify paragraph 4 of 3.3.3 [basic.scope.local] as follows:
Editorial Note: the wording above is identical to what is in the current working paper. It is given here for completeness.
Modify paragraph 1 of 6.5 [stmt.iter] as follows:
iteration-statement:[ Note: a for-init-statement ends with a semicolon. -- end note ]
while ( condition ) statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ; expressionopt ) statement
for ( for-range-declaration : expression ) statement
for-init-statement:
expression-statement
simple-declaration
for-range-declaration:
type-specifier-seq attribute-specifieropt declarator
Editorial Note: the wording above is identical to what is in the current working paper. It is given here for completeness.
Add a new section 6.5.4 Range-based for statement [stmt.ranged], as indicated:
The range-based for statement
for (
for-range-declaration:
expression)
statementis equivalent to
{ auto && __range = ( expression ); 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,_RangeT
is the type of theexpression
, andbegin-expr
andend-expr
are determined as follows:
- If
_RangeT
is an array type,begin-expr
andend-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.
- Otherwise,
begin-expr
andend-expr
arebegin(__range)
andend(__range)
, respectively, wherebegin
andend
are looked up with argument-dependent lookup ([basic.lookup.argdep]). For the purposes of this name lookup, namespacestd
is an associated namespace.
[ Example:
int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2;--end example]
Modify the header <initializer_list> synopsis in section 18.9 Initializer lists [support.initlist] by adding the following to the synopsis:
namespace std { // ... // 18.9.3 initializer list range access [support.initlist.range] template<typename E> const E* begin(initializer_list<E> il); template<typename E> const E* end(initializer_list<E> il); }
Add a new section 18.9.3 initializer list range access [support.initlist.range], with the following text:
template<typename E> const E* begin(initializer_list<E> il);
- Returns:
il.begin()
template<typename E> const E* end(initializer_list<E> il);
- Returns:
il.end()
Modify the section 20.2 Header <utility> synopsis by adding the following to the synopsis:
// 20.2.3 pair range access [pair.range] template<typename InputIterator> InputIterator begin(const std::pair<InputIterator, InputIterator>& p); template<typename InputIterator> InputIterator end(const std::pair<InputIterator, InputIterator>& p);
Add a new section 20.2.3 pair range access [pair.range], with the following text:
template<typename InputIterator> InputIterator begin(const std::pair<InputIterator, InputIterator>& p);
- Returns:
p.first
template<typename InputIterator> InputIterator end(const std::pair<InputIterator, InputIterator>& p);
- Returns:
p.second
Modify the section 20.5.1 Header <tuple> synopsis by adding the following to the synopsis:
// 20.5.2.8 tuple range access [tuple.range] template<typename InputIterator> InputIterator begin(const std::tuple<InputIterator, InputIterator>& t); template<typename InputIterator> InputIterator end(const std::tuple<InputIterator, InputIterator>& t);
Add a new section 20.5.2.8 tuple range access [tuple.range], with the following text:
template<typename InputIterator> InputIterator begin(const std::tuple<InputIterator, InputIterator>& t);
- Returns:
std::get<0>(t)
template<typename InputIterator> InputIterator end(const std::tuple<InputIterator, InputIterator>& t);
- Returns:
std::get<1>(t)
Modify the section 24.3 Header <iterator> synopsis [iterator.syn] by adding the following at the end of the synopsis:
// 24.7 range access [iterator.range] template<typename C> auto begin(C& c) -> decltype(c.begin()); template<typename C> auto begin(const C& c) -> decltype(c.begin()); template<typename C> auto end(C& c) -> decltype(c.end()); template<typename C> auto end(const C& c) -> decltype(c.end()); template<typename T, size_t N> T* begin(T (&array)[N]); template<typename T, size_t N> T* end(T (&array)[N]);
Add a new section 24.7 range access [iterator.range] containing the following:
- In addition to being available via inclusion of the <
iterator
> header, the function templates in [iterator.range] are also available when any of the following headers are included: <array
>, <deque
>, <forward_list
>, <list
>, <map
>, <regex
>, <set
>, <string
>, <unordered_map
>, <unordered_set
>, or <vector
>.template<typename C> auto begin(C& c) -> decltype(c.begin()); template<typename C> auto begin(const C& c) -> decltype(c.begin());
- Returns:
c.begin()
template<typename C> auto end(C& c) -> decltype(c.end()); template<typename C> auto end(const C& c) -> decltype(c.end());
- Returns:
c.end()
template<typename T, size_t N> T* begin(T (&array)[N]);
- Returns:
array
template<typename T, size_t N> T* end(T (&array)[N]);
- Returns:
array + N
Modify the section 24.6.1 Header <valarray> synopsis [valarray.syn] by adding the following at the end of the synopsis:
template<typename T> unspecified-1 begin(valarray<T>& v); template<typename T> unspecified-2 begin(const valarray<T>& v); template<typename T> unspecified-1 end(valarray<T>& v); template<typename T> unspecified-2 end(const valarray<T>& v);
Add a new section 26.6.10 valarray range access [valarray.range] containing the following:
- In the
begin
andend
function templates that follow, unspecified-1 is a type that meets the requirements of a mutable random access iterator ([random.access.iterators]) whosevalue_type
is the template parameterT
and whosereference
type isT&
. unspecified-2 is a type that meets the requirements of a constant random access iterator ([random.access.iterators]) whosevalue_type
is the template parameterT
and whosereference
type isconst T&
.template<typename T> unspecified-1 begin(valarray<T>& v); template<typename T> unspecified-2 begin(const valarray<T>& v);
- Returns: an iterator referencing the first value in the numeric array
template<typename T> unspecified-1 end(valarray<T>& v); template<typename T> unspecified-2 end(const valarray<T>& v);
- Returns: an iterator referencing one past the last value in the numeric array
Add #include <initializer_list>
to the
synopsis for the following headers:
<string>
21.3 String classes [string.classes] <array>
,<deque>
,<forward_list>
,<list>
,<queue>
,<stack>
, and<vector>
23.3 Sequence containers [sequences] <map>
and<set>
23.4 Associative containers [associative] <unordered_map>
and<unordered_set>
23.5 Unordered associative containers [unord] <algorithm>
25.2 Header <algorithm> synopsis [algorithms.syn] <random>
26.5.1 Header <random> synopsis [rand.synopsis] <valarray>
26.6.1 Header <valarray> synopsis [valarray.syn] <regex>
28.4 Header <regex> synopsis [re.syn]
James Widman identified several deficiencies in drafts of this proposal and provided fixes for them.
Steve Adamczyk, Alberto Ganesh Barbati, Walter E Brown, Gabriel Dos Reis, Daniel Krügler, Jens Maurer, Thorsten Ottosen, Bjarne Stroustrup, Herb Sutter, and James Widman participated in discussions, reviewed drafts, and suggested improvements.