带有文字列表的范围 for 循环?

问题描述 投票:0回答:2

在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
   ...
}
c++ c++11 for-loop initializer-list
2个回答
19
投票

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


是的,这是有效的。

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

你的braced-init-list(通过

auto
)推导出
std::initializer_list
,这很方便,因为这些东西可能会被迭代。

[..] 用于基于范围的

for
形式的语句

for (
for-range-声明
:
支撑初始化列表
) 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 支持此功能,但是,由于“Visual Studio 11”实际上是 Visual Studio 2012,因此您需要升级才能赶上:初始化程序列表完全不受支持,直到 Visual Studio 2013.


6
投票

这是一个例子

#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>
    

© www.soinside.com 2019 - 2024. All rights reserved.