在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
...
}
tl;dr: 升级您的编译器以获得巨大成功。
是的,这是有效的。
[C++11: 6.5.4/1]
中 ranged-for 的定义为我们提供了该构造的两种语法变体。一个采用 :
右侧的 表达式,另一个采用 braced-init-list。
你的braced-init-list(通过
auto
)推导出std::initializer_list
,这很方便,因为这些东西可能会被迭代。
[..] 用于基于范围的
形式的语句for
for-range-声明for (
支撑初始化列表:
) 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.
这是一个例子
#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>