C++ 基于范围的for循环中变量的重新声明
此代码不符合GCC 4.8.1,但适用于MSVC2013: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]明确指出
#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
}
}