我已经使用stl在下面声明了一个地图,并在其中插入了一些值。
#include<bits/stdc++.h>
int main()
{
map<int,int> m;
m[1]=1;
m[2]=1;
m[3]=1;
m[4]=1;
m[5]=1;
m[6]=1;
for(auto it=m.begin();it!=m.end();)
{
cout<<it->first<<" "<<it->second<<endl;
it=it++;
}
return 0;
}
当我执行上面编写的代码时,它最终处于无限循环中。有人能告诉我它为什么这样做吗? 我正在递增迭代器的值,然后它被存储在它中,它应该在下次循环执行时递增,最终它应该正常终止。我错了吗?
答案 0 :(得分:3)
坏线是it = it++;
。这是未定义的行为!因为它没有被定义,所以当它增加时,在你的情况下,它再次在它自己的辅助之前增加,它之前的值增加再次分配给它,所以它保持在第一个位置。 正确行将为it = ++it;
或仅++it;
/ it++;
,因为它会自行更改。
这只是内置类型未定义,但在这里由stl中地图的源代码定义。
答案 1 :(得分:1)
如果您尝试使用int
执行类似操作,则会收到警告:
int nums[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof nums / sizeof *nums; ) {
cout << nums[i] << '\n';
i = i++;
}
warning: operation on 'i' may be undefined [-Wsequence-point]
但是,当您使用具有运算符重载的类(std::map::iterator
)时,编译器可能并不聪明地检测到它。
换句话说,您所做的是违反序列点,因此行为是未定义的行为。
答案 2 :(得分:1)
后增量操作的行为如下:
iterator operator ++ (int) {
auto copy = *this;
++*this;
return copy;
}
因此,增量步骤会发生什么,迭代器it
会被原始值的副本覆盖。如果map
不为空,则循环将保持在第一个元素上。