使用文字列表进行循环操作?

时间:2014-02-10 22:39:35

标签: c++ c++11 for-loop initializer-list

在C ++ 11中,是否可以编写以下内容

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

就像这样

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

2 个答案:

答案 0 :(得分:16)

tl; dr:升级您的编译器取得巨大成功。


是的,这是有效的。

[C++11: 6.5.4/1]中ranged-for的定义为我们提供了两种语法变体。一个在:的右侧采用表达式,另一个采用 braced-init-list

你的 braced-init-list 推断(通过auto)到std::initializer_list,这很方便,因为这些东西可能会被迭代。

  

[..] 表格的基于范围的for声明

     

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

     

range-init 等同于 braced-init-list 。在每种情况下,基于范围的for语句等同于

{
   auto && __range = range-init;
   for ( auto __begin = begin-expr,
              __end = end-expr;
        __begin != __end;
        ++__begin ) {
      for-range-declaration = *__begin;
      statement
   }
}
     

[..]

所以,你基本上是在说:

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

(我在这里没有受到通用引用的困扰。)

反过来或多或少等同于:

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

现在,GCC 4.8 supports this但是,由于“Visual Studio 11”实际上是Visual Studio 2012,因此您需要进行升级才能赶上: initialiser lists were not supported at all until Visual Studio 2013

答案 1 :(得分:4)

可以将此构造与初始化列表一起使用。简单来说,您使用的MS VC ++似乎不支持它。

这是一个例子

#include <iostream>
#include <initializer_list>

int main() 
{
    for (int n : { 1, 5, 6, 2, 9 }) std::cout << n << ' ';
    std::cout << std::endl;

    return 0;
}

您必须包含标头<initializer_list>,因为for语句中的初始化列表转换为std::initializer_list<int>