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

标签 c++11 for-loop visual-c++

此代码在 Visual Studio 2015 更新 3 中编译(在这里: visual C++ compiler online ,并且在我在线尝试的其他编译器(GCC 和 CLANG)中没有编译,给出重新声明错误

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

output: 1 99 2 99 3 99



VS C++ 在线编译器(版本:19.10.24903.0)对此发出警告:

warning C4456: declaration of 'i' hides previous local declaration



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

在我看来,VS2015 正在为“auto i”创建一个范围,并为循环体创建一个内部范围。

正如一位同事所建议的那样,添加一个额外的范围在我测试过的其他编译器中编译得很好(不是我想要这个,这只是出于好奇):
vector<int> v = {1,2,3};
for (auto i : v) {{
  printf("%d ", i);
  int i = 99;
  printf("%d ", i);
}}

谢谢

编辑:
好的,在阅读了另一个问题 Redeclaration of variable in range-based for loops 和“Angew”的答案后,我相信 VS 实际上是正确的。

我在这里阅读:cpp reference

鉴于此语法描述:
for ( range_declaration : range_expression ) loop_statement

这相当于:
{
 auto && __range = range_expression ; 
 for (auto __begin = begin_expr, __end = end_expr; 
  __begin != __end; ++__begin) { 
    range_declaration = *__begin; 
    loop_statement
 } 
} 

我知道 loop_statement 实际上是我的整个块,包括括号,因此重新定义确实在内部块中,因此有效。

编辑 2:
我的最后一次编辑,以供将来引用,阅读传统的 for loop 语法与基于范围的情况类似( cpp for loop ):
for ( init-statement condition(optional); iteration_expression(optional) ) statement

“上述语法产生的代码等效于:”
{
   init_statement 
   while ( condition ) { 
     statement 
     iteration_expression ; 
   }
}

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

最佳答案

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

Names declared in the init-statement , the for-range-declaration , and in the condition of if , while , for , and switch statements are local to the if , while , for , or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4



缩短:

Names declared in the ... for-range-declaration ... are local to the ... for ... and shall not be redeclared in a subsequent condition of that statement nor in the outermost block



我读这个是说它不应该被允许。

关于基于范围的 for 循环中的 C++11 重新声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41796441/

相关文章:

c++ - C++11 中的 3 默认成员弃用规则

C++ 类型索引散列导致未定义的行为

c++ - 如何在 C++ 的 STL 容器值中拥有 const 成员?

c++ - 是否允许实现将公共(public)成员添加到标准类型?

使用 C 将字符串中的所有其他字母字符更改为大写

c++ - 为什么 detectMultiScale 不返回面孔?

visual-studio - 如何在 Visual C++ 2017 中链接静态库?

c++ - 为什么有些函数分布密集,而另一些函数则用 int 3 指令对齐和填充?

batch-file - Windows 批处理中缺少操作数错误

r - 如何构建一个循环数据帧并转换其中数据的函数 (R)