Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于范围的for循环中变量的重新声明_C++_Visual Studio_Gcc_C++11 - Fatal编程技术网

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

C++ 基于范围的for循环中变量的重新声明,c++,visual-studio,gcc,c++11,C++,Visual Studio,Gcc,C++11,此代码不符合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"; } } 这是MSVC 2013编译器中的一些错误吗?是的,这是一个错误,但在GCC中。C++11[stmt.range]明确指出

此代码不符合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";
  }
}

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

是的,这是一个错误,但在GCC中。C++11[stmt.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实际上很好地接受了它。

这是GCC中的一个错误,也是

for(range\u声明:range\u表达式){loop\u语句}

相当于

{
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.range]告诉我们循环的范围扩展为:

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

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

那么你的意思是基于范围的for和“正常for”不应该表现相同?@Korchkidu是的,它们在这方面表现不同。是的,的确如此。似乎基于范围的for循环将for范围声明置于“中间”范围内。实际上,在外部范围内重新定义变量也是可以的。至少可以这么说,这是违反直觉的。来自[stmt.range]的for-rage循环并不等同于您所写的。这些语句没有作用域(
std::string i=“oups”
在您的情况下)@Bццћ有何区别?注意,我已经根据OP的情况和要点用它们的定义替换了
beginexpr
end expr
。我不是为循环提供基于范围的
的一般定义,而是展示OP的循环在形式上等同于什么。基于范围的for循环的产品是“
for
for range declaration
expression
语句”。在该产品中没有文本
{
,这意味着OP案例中的语句是整个复合语句。
{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
        __end = end-expr;
        __begin != __end;
        ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}