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

Tho*_*ing 7 c++ for-loop initializer-list c++11

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

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

像这样的事情

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

Lig*_*ica 16

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


是的,它是有效的.

ranged-for的定义[C++11: 6.5.4/1]为我们提供了这种结构的两种语法变体.一个表达在右侧:,另一个表示braced-init-list.

你的braced-init-list推导(通过auto)到a 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
   }
}
Run Code Online (Sandbox Code Playgroud)

[..]

所以,你基本上是这样说的:

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

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

这反过来或多或少相当于:

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

现在,GCC 4.8支持这一点,但是,由于"Visual Studio 11"实际上是Visual Studio 2012,您需要升级才能赶上: Visual Studio 2013之前,根本不支持初始化列表.


Vla*_*cow 6

可以将此构造与初始化列表一起使用。只是您使用的 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;
}
Run Code Online (Sandbox Code Playgroud)

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