问题
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
...
}
回答1:
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.
回答2:
It is possible to use this construction with an initializer list. Simply it seems the MS VC++ you are using does not support it.
Here is an example
#include <iostream>
#include <initializer_list>
int main()
{
for (int n : { 1, 5, 6, 2, 9 }) std::cout << n << ' ';
std::cout << std::endl;
return 0;
}
You have to include header <initializer_list>
because the initializer list in the for statement is converted to std::initializer_list<int>
来源:https://stackoverflow.com/questions/21689388/ranged-for-loop-with-literal-list