虽然我使用像这样的迭代器,
//include header files
using namespace std;
int main()
{
map<int,int> intIntMap;
map<int,int>::iterator pos;
pos = intIntMap.begin();
intIntMap[0] = 1;
intIntMap[3] = 5;
intIntMap[4] = 9;
intIntMap[5] = 5;
//遍历
cout << (*pos).first << endl;
while( pos != intIntMap.end() )
{
cout << pos->first << " <---> " << pos->second << endl;
pos++;
}
}
输出为4;
但是我使用像这样的迭代器:
//include header file
using namespace std;
int main()
{
map<int,int> intIntMap;
map<int,int>::iterator pos;
intIntMap[0] = 1;
intIntMap[3] = 5;
intIntMap[4] = 9;
intIntMap[5] = 5;
//遍历
pos = intIntMap.begin();
cout << (*pos).first << endl;
while( pos != intIntMap.end() )
{
cout << pos->first << " <---> " << pos->second << endl;
pos++;
}
}
输出是我想要的;
我想知道迭代器的使用之间有什么区别,当我插入新的键值对时,第一个迭代器会发生什么?谢谢!
addtion: 编译是使用gcc 4.1.2,感觉比较混乱,像这样:
答案 0 :(得分:10)
由于在容器为空时调用了begin()
,因此得到的迭代器等于end()
(§23.1/ 7:“如果容器为空,则begin()== end ()“)。
将项目插入容器并没有改变这一点,因此您仍然拥有pos == intIntMap.end()
。
然后执行循环的零迭代,因为pos==end()
,并且只在pos != end()
执行循环。
在第二个示例中,您在插入数据后设置pos()
,因此您获得了集合中的第一个项目,并迭代到最后一个项目。
编辑:就打印出地图的内容而言,我可能更喜欢这样做:
std::ostream &operator<<(std::ostream &os, std::pair<int, int> const &d) {
return os << d.first << " <---> " << d.second;
}
// ...
std::copy(intIntMap.begin(), intIntMap.end(),
std::ostream_iterator<std::pair<int, int> >(std::cout, "\n"));
答案 1 :(得分:2)
使用gdb进行此操作,我发现迭代器的first
字段随着每次添加键值对而发生变化。似乎没有数据的地图的迭代器(由begin()
返回)包含关于地图本身的一些元数据,特别是地图的大小(所述迭代器的first
字段随着每个增长而增长添加键值对)。在添加单个键值对后调用begin()
检索迭代器会导致“预期”行为。
答案 2 :(得分:-1)
迭代器旨在用于自迭代器实例化以来尚未修改的容器。第一个例子中的代码输出是未定义的,根据c ++标准(你仍然可以获得你想要的结果,你只是不能保证得到它,而且没有太多理由可以期待它。)
在第一种情况下迭代器没有发生任何事情,但是您打算引用它的容器已经发生了变化,并且不一定在内存中的同一位置。
答案 3 :(得分:-1)
容器修改使现有迭代器无效。
通常的做法是在使用之前获取迭代器,然后将其丢弃。您可以像这样使用for
:
#include <iostream>
#include <map>
using namespace std;
int main ()
{
map<int, int> mymap;
mymap[0] = 100;
mymap[1] = 200;
mymap[2] = 300;
// show content:
for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++)
cout << (*it).first << " => " << (*it).second << endl;
return 0;
}
答案 4 :(得分:-1)
简短回答:修改容器内容后,无法保证迭代器仍然有效。
由于此处的容器是map
,通常实现为红黑树,因此在插入期间修改并重新平衡结构。
在第一个示例中,您将迭代器pos
初始化为地图的开头。此时,迭代器对当前内容有效。但是一旦开始添加元素,迭代器就不再指向重组容器的新begin
位置。
因此,第二个示例的工作原因是因为在完成对容器的所有修改后,您将迭代器设置为begin
。
通常,在迭代结构时修改结构是个坏主意。
这个问题有关于迭代器有效性的更多细节: