繁体   English   中英

基于现有变量循环的范围

[英]range based for loop with existing variable

在C ++ 11中使用基于for循环的范围和现有变量,我希望该变量用循环后的最后一次迭代的值填充。 但是,当我测试它时,我得到了不同的结果。

例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
  std::vector<int> v;
  v.push_back(2);
  v.push_back(43);
  v.push_back(99);

  int last = -50;
  for (last : v)
    std::cout << ":" << last << "\n";

  std::cout << last;
  return 0;
}
  1. MSVC 2013似乎不支持基于范围的循环而没有类型声明
  2. GCC-5.1自动引入一个新变量或将其设置回初始值,给出

    :2
    :43
    :99
    -50

我想MSVC再次成为MSVC,但是GCC在这里呢? 为什么last不是99的最后一行?


根据标准定义 ,我会期待我在第一句中描述的行为。

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

range_declarationlast而不是int last ,这应该修改现有变量。

海湾合作委员会实施了标准提案n3994 ,其中for (elem : range)表示for (auto&& elem : range)语法糖。 这没有进入C ++ 17,因此已从更新版本的GCC中删除了该功能。

用于迭代范围的命名变量必须是[stmt.ranged]的声明,因此您的代码不应该编译。

您的代码无法从gcc 6.1(以及所有clang版本)开始编译:

main.cpp:12:8: error: range-based for loop requires type for loop variable
  for (last : v)
       ^
       auto &&

它看起来像以前的版本在这里隐式使用auto。 你得到-50作为最后输出的事实是,因为for引入了最后一个本地范围,所以之后for两端,最后从使用外部范围。


我做了一点挖掘,这是故意在gcc: N3994,terse range-for ,其中很快就会做到:

A range-based for statement of the form
    for ( for-range-identifier : for-range-initializer ) statement
is equivalent to
    for ( auto&& for-range-identifier : for-range-initializer ) statement

然后它没有进入c ++ 17并在此处删除:

https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=229632

根据标准,基于for循环的范围产生相同的输出:

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

如您所见,迭代变量__begin正在其自己的范围内定义。

为什么最后一行不是99?

你有两个变量叫做last 一个属于主函数的范围并保持值-50 第二个变量在基于循环的范围内定义。

在循环内部,打印last变量打印来自同一范围的变量(即,从基于循环的范围)。 然而,在循环之后,打印last将再次打印来自相同范围的变量,即保持-50

你的程序不能用我的g ++ 4.9.2编译。

使用clang ++ 3.5进行编译(带有警告:“基于范围的for循环,隐式推导类型是C ++ 1z扩展[-Wc ++ 1z-extensions]”)

但是clang ++使用不同的last变量

用以下修改过的程序

#include <iostream>
#include <vector>
using namespace std;

int main() {
  std::vector<int> v;
  v.push_back(2);
  v.push_back(43);
  v.push_back(99);

  int last = -50;

  std::cout << "extern last pointer: " << long(&last) << '\n';

  for ( last : v)
   {
     std::cout << ": " << last << " ; pointer: " << long(&last) << '\n';
   }

  std::cout << "extern last pointer again: " << long(&last) << '\n';
  std::cout << ": " << last << std::endl;

  return 0;
}

我得到以下输出

extern last pointer: 140721376927168
: 2 ; pointer: 38101008
: 43 ; pointer: 38101012
: 99 ; pointer: 38101016
extern last pointer again: 140721376927168
: -50

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM