基于现有变量循环的范围

Nik*_*s R 19 c++ gcc for-loop visual-c++ c++11

在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;
}
Run Code Online (Sandbox Code Playgroud)
  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 
  } 
} 
Run Code Online (Sandbox Code Playgroud)

range_declarationlast和否int last,这应该修改现有的变量.

Tar*_*ama 18

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

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

  • 我接受这个答案,因为它是唯一一个声明“:”的左侧实际上必须是一个声明,而不是一个任意表达式,并且包含对标准的引用。谢谢!:) (2认同)

mar*_*inj 9

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

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

它看起来像以前的版本在这里隐式使用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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 所以MSVC不再是MSVC了! (5认同)