Title
braced-init-list in the range-based for statement
Status
c++11
Section
8.6.5 [stmt.ranged]
Submitter
James Widman

Created on 2009-04-07.00:00:00 last changed 122 months ago

Messages

Date: 2010-08-23.00:00:00

[Voted into WP at August, 2010 meeting.]

Date: 2022-11-20.07:54:16

Note to editor:

The formatting in the preceding change for range-init follows that of the existing text for begin-expr and end-expr. However, CWG is concerned that this style makes all of these elements look too much like grammar nonterminals and asks that the editor consider some other formatting convention.

Date: 2010-06-15.00:00:00

Proposed resolution (June, 2010):

  1. Change 8.6 [stmt.iter] paragraph 1 as follows:

  2. Iteration statements specify looping.

      iteration-statement:
        while ( condition ) statement
        do statement while ( expression ) ;
        for ( for-init-statement conditionopt ; expressionopt ) statement
        for ( for-range-declaration : expression for-range-initializer ) statement

      for-init-statement:
        expression-statement
        simple-declaration

      for-range-declaration:
        type-specifier-seq attribute-specifieropt declarator

      for-range-initializer:
        expression
        braced-init-list

    [Note: a for-init-statement ends with a semicolon. —end note]

  3. Change 8.6.5 [stmt.ranged] paragraph 1 as follows:

  4. The For a range-based for statement of the form

      for ( for-range-declaration : expression ) statement

    let range-init be equivalent to the expression surrounded by parentheses:

      ( expression )

    [Footnote: this ensures that a top-level comma operator cannot be reinterpreted as a delimiter between init-declarators in the declaration of __range. —end footnote] and for a range-based for statement of the form

      for ( for-range-declaration : braced-init-list ) statement

    let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to

      {
        auto && __range = ( expression ) range-init;
        for ( auto __begin = begin-expr,
        ...
    
Date: 2009-04-07.00:00:00

The intent is that the range-based for statement should be able to be used with a braced-init-list as the range over which to iterate. However, this does not work grammatically: a braced-init-list is not an expression, as required by the syntax in 8.6.5 [stmt.ranged] paragraph 1:

    for ( for-range-declaration : expression ) statement

Even if this were resolved, the “equivalent to” code is not correct. It contains the declaration,

    auto && __range = ( expression );

This has a similar problem, in that 9.2.9.7 [dcl.spec.auto] paragraph 3 requires that the initializer have one of the forms

    = assignment-expression
    ( assignment-expression )

which does not allow for a braced-initializer-list. In addition, although not allowed by the grammar, 9.2.9.7 [dcl.spec.auto] paragraph 6 treats the braced-init-list specially, in order for the type deduction to work correctly:

Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (9.4.5 [dcl.init.list]), with std::initializer_list<U>.

The problem here is that a parenthesized initializer, as in the code expansion of the range-based for statement, is not a braced-init-list.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: wp -> fdis
2010-11-29 00:00:00adminsetstatus: dr -> wp
2010-08-23 00:00:00adminsetmessages: + msg2910
2010-08-23 00:00:00adminsetmessages: + msg2909
2010-08-23 00:00:00adminsetstatus: review -> dr
2010-02-16 00:00:00adminsetmessages: + msg2531
2010-02-16 00:00:00adminsetstatus: drafting -> review
2009-11-08 00:00:00adminsetstatus: open -> drafting
2009-04-07 00:00:00admincreate