C++11 C++;11在基于范围的for循环中重新声明

C++11 C++;11在基于范围的for循环中重新声明,c++11,for-loop,visual-c++,C++11,For Loop,Visual C++,这段代码在Visual Studio 2015 update 3(此处:)中编译,在我在线尝试过的其他编译器(GCC和CLANG)中没有编译,因此出现了重新声明错误 vector<int> v = {1,2,3}; for (auto i : v) { printf("%d ", i); int i = 99; printf("%d ", i); } 这相当于: { auto && __range = range_expression ; for

这段代码在Visual Studio 2015 update 3(此处:)中编译,在我在线尝试过的其他编译器(GCC和CLANG)中没有编译,因此出现了重新声明错误

vector<int> v = {1,2,3};
for (auto i : v) {
  printf("%d ", i);
  int i = 99;
  printf("%d ", i);
}
这相当于:

{
 auto && __range = range_expression ; 
 for (auto __begin = begin_expr, __end = end_expr; 
  __begin != __end; ++__begin) { 
    range_declaration = *__begin; 
    loop_statement
 } 
} 
{
   init_statement 
   while ( condition ) { 
     statement 
     iteration_expression ; 
   }
}
我知道,loop_语句实际上是我的整个块,包括括号,因此重新定义确实在一个内部块中,因此是有效的

编辑2: 我的上一次编辑,为了将来参考,阅读传统的循环语法与基于范围的语法类似()

for ( init-statement condition(optional); iteration_expression(optional) ) statement
“上述语法生成的代码等效于:”

因此回顾过去,我还可以将/parse语句解释为我的内部块,包括大括号,我至少希望我在任何编译器中都能保持一致的行为。但是所有编译器都会为传统的for循环重新声明错误。

N4606(C++17草稿)3.3.3 basic.scope.block,第4节

声明中声明的名称 初始化语句 这个 用于范围声明 ,在 条件 属于 如果 , 虽然 , 对于 ,及 转换 语句是本地的 如果 , 虽然 , 对于 或 转换 报表(包括受控报表), 且不得在该声明的后续条件中或在最外层区块重新声明(或 这个 如果 语句,受控语句的任何最外层块);参见6.4

缩短:

在…for range declaration…中声明的名称是…for…的本地名称,不得在该语句的后续条件中或在最外层块中重新声明

我读这篇文章是说这是不允许的

C++11规范中是否有一些空间允许两种实现都有效

除了一个例外,唯一的答案是否定的


全局变量例外,在全局变量中可以使用作用域操作符
来访问它们。否则,如果在外部作用域中对变量的名称进行阴影处理,您将无法再访问它。

我刚才看到了另一个问题,该问题说明VS实际上是正确的,因为正则for循环等于,而它后面的EXCEPT部分谈到了标识符的作用域,但您可以在嵌套上下文中重新声明它,对吗?我接受这一点作为答案,作为提供的参考,尽管不同的实现如何解释此语法缺乏一致性至少让人感到不安。谢谢。我还对com几年后,皮尔斯仍然不同。但再次强调,这取决于你如何阅读“声明”或“最外层的块”。如果这适用于的直接语句的范围,则MSVC是正确的,但如果它适用于该位置的块,则GCC/Clang是正确的。问题是阴影本身的合法性,而不是阴影变量的可访问性。
for ( init-statement condition(optional); iteration_expression(optional) ) statement
{
   init_statement 
   while ( condition ) { 
     statement 
     iteration_expression ; 
   }
}