在基于范围的for循环中重新声明变量

Redeclaration of variable in range-based for loops

本文关键字:新声明 变量 声明 循环 于范围 范围 for      更新时间:2023-10-16

此代码在GCC 4.8.1中失败,但可以在MSVC2013中工作:

#include <vector>
#include <string>
int main()
{
  std::vector<int> V{1,2,3,4,5};
  for (auto i : V)
  {
    std::string i = "oups";
  }
}

prog.cpp:10:17: error: redeclaration of ‘std::string i’
     std::string i = "oups";
                 ^

是MSVC 2013编译器中的一些错误吗?

是的,这是一个bug,但是在GCC中。c++ 11[支撑。range]清楚地说明基于range的for循环相当于:

{
  auto && __range = (V);
  for ( auto __begin = __range.begin(),
             __end = __range.end();
        __begin != __end;
        ++__begin ) {
    auto i = *__begin;
    {
      std::string i = "oups";
    }
  }
}

因此,内部i应该简单地隐藏环控i而不会出现任何问题。

这是GCC和Clang中的一个bug

参见Range Based For-loop

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;
            {  // Notice brace
               loop_statement 
            } // Notice ending brace
} 
} 
关于Visual c++ 2013
for (auto i : V) std::string i = "oups"; 
       /* match this with equivalent for-loop
          loop-statement aren't in braces
      */

不能编译。

c++11 [stmt. cn]range]告诉range-for循环展开成这样:

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

与其他答案相反,我声称语句没有作用域,这是MSVC的错误(不是gcc或clang)。