C++11 C++;11在基于范围的for循环中重新声明
这段代码在Visual Studio 2015 update 3(此处:)中编译,在我在线尝试过的其他编译器(GCC和CLANG)中没有编译,因此出现了重新声明错误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
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 ;
}
}