for_each for bariloche c++ for-loop c++11 scope

for - iterate map c++ 11



Identificador con el mismo nombre tanto en la expresión como en la declaración de rango basado en (3)

De mi lectura de C ++ 2011 6.5.4, su código de:

bar b; for(int b : b.nums) std::cout << b << std::endl;

Debe ser convertido a:

bar b; { auto && __range = b.nums; for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin ) { int b = *__begin; std::cout << b << std::endl; } }

Esto para mí significa que el ruido es correcto.

¿Es legal declarar una variable de bucle en un bucle for basado en rangos con el mismo nombre que uso en la declaración de expresión del bucle? Espero que el ejemplo lo aclare.

#include <iostream> #include <vector> struct bar { std::vector<int> nums; }; int main() { bar b; b.nums = {1, 2, 3}; for(int b : b.nums) std::cout << b << std::endl; }

gcc 4.8 da un error mientras que clang 3.2 lo permite.


Por lo que vale la pena, este error ahora se ha corregido en el tronco gcc. :)


Clang tiene razón .

El párrafo 6.5.4 / 1 de la norma C ++ 11 define la declaración basada en el rango de la siguiente manera:

Para una declaración basada en el rango del formulario

for ( for-range-declaration : expression ) statement

Deje que range-init sea ​​equivalente a la expresión entre paréntesis.

( expression )

y por un rango basado en la declaración de la forma

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

Deje que range-init sea ​​equivalente a la lista-init marcada. En cada caso, una declaración basada en rango es equivalente a

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

De lo anterior, es visible que la variable b , que corresponde a la for-range-declaration , se declara dentro de una declaración de bloque anidada, mientras que el inicializador range-init (que corresponde a b.nums ) aparece en el ámbito principal, donde b debe resolver al objeto de tipo bar .