Search code examples
c++c++11for-loopinitializer-list

Ranged for loop with literal list?


In C++11, is it possible to write the following

int ns[] = { 1, 5, 6, 2, 9 };
for (int n : ns) {
   ...
}

as something like this

for (int n : { 1, 5, 6, 2, 9 }) { // VC++11 rejects this form
   ...
}

Solution

  • tl;dr: Upgrade your compiler for great success.


    Yeah, it's valid.

    The definition of ranged-for in [C++11: 6.5.4/1] gives us two variants of syntax for this construct. One takes an expression on the right-hand-side of the :, and the other takes a braced-init-list.

    Your braced-init-list deduces (through auto) to a std::initializer_list, which is handy because these things may be iterated over.

    [..] 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 = range-init;
       for ( auto __begin = begin-expr,
                  __end = end-expr;
            __begin != __end;
            ++__begin ) {
          for-range-declaration = *__begin;
          statement
       }
    }
    

    [..]

    So, you are basically saying:

    auto ns = { 1, 5, 6, 2, 9 };
    for (int n : ns) {
       // ...
    }
    

    (I haven't bothered with the universal reference here.)

    which in turn is more-or-less equivalent to:

    std::initializer_list<int> ns = { 1, 5, 6, 2, 9 };
    for (int n : ns) {
       // ...
    }
    

    Now, GCC 4.8 supports this but, since "Visual Studio 11" is in fact Visual Studio 2012, you'll need to upgrade in order to catch up: initialiser lists were not supported at all until Visual Studio 2013.