当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《基于范围的for循环中的C++11重新声明》经验,为你挑选了1个好方法。

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

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

输出:1 99 2 99 3 99

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

警告C4456:'i'声明隐藏了之前的本地声明

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

在我看来,VS2015正在为"auto i"创建一个范围,并且是循环体的内部范围.

正如同事建议的那样,添加一个额外的范围,在我测试的其他编译器中编译得很好(不是我想要这个,只是为了好奇):

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

谢谢

编辑: 好的,在阅读了另一个问题后,基于范围的for循环中的变量重新声明和"Angew"的答案,我相信VS实际上是正确的.

我在这里读到:cpp参考

鉴于此语法描述:

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循环语法是一个类似的情况(循环的cpp)作为基于范围:

for ( init-statement condition(optional); iteration_expression(optional) ) statement

"以上语法产生的代码相当于:"

{
   init_statement 
   while ( condition ) { 
     statement 
     iteration_expression ; 
   }
}

所以回过头来看,我也可以解释/解析语句作为我的内部块,包括大括号,我至少期望在其中编译器的一致行为.但是所有编译器都会因为传统的for循环重新声明错误而挽救.



1> dascandy..:

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

在init-statement,for-range-declaration以及if,while,for和switch语句的条件中声明的名称是if,while,for或switch语句(包括受控语句)的本地名称,以及不得在该陈述的后续条件下,也不得在受控陈述的最外面的区块(或对于if语句,任何最外面的区块)重新宣布; 见6.4

缩短:

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

我读到这个说不应该被允许.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有