在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;
}
GCC-5.1自动引入新变量或将其设置回初始值,给出
:2个
:43
99
-50
我猜MSVC再次成为MSVC,但是GCC在这里呢?为什么最后一行last
不是99
?
鉴于definition by the standard,我希望我在第一句话中描述的行为。
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
range_declaration
为last
而不是int last
,这应修改现有变量。
答案 0 :(得分:18)
GCC实施了标准提案n3994,这表明for (elem : range)
是for (auto&& elem : range)
的语法糖。这并没有进入C ++ 17,因此已从更新版本的GCC中删除了该功能。
用于迭代范围的命名变量必须是[stmt.ranged]
的声明,因此您的代码不应该编译。
答案 1 :(得分:9)
您的代码无法从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
引入了last的本地范围,所以在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
答案 2 :(得分:0)
根据标准,基于for循环的范围产生与:
相同的输出{
auto&& __range = expression;
for (auto __begin = begin-expression,
__end = end-expression;
__begin != __end;
++__begin)
{
declaration = *__begin;
statement
}
}
如您所见,迭代变量__begin
正在其自己的范围内定义。
为什么最后一行中的最后一个不是99?
您有两个名为last
的变量。一个属于main函数的范围,并保存值-50
。第二个变量在基于循环的范围内定义。
在循环内部,打印last
变量打印来自同一范围的变量(即来自基于循环的范围)。然而,在循环之后,打印last
将再次打印来自同一范围的变量,该范围是-50
答案 3 :(得分:0)
你的程序没有用我的g ++ 4.9.2编译。
使用clang ++ 3.5进行编译(带有警告:&#34;基于范围的for循环,带隐式推导类型是C ++ 1z扩展[-Wc ++ 1z-extensions]&#34;)
但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