我试图通过向量反向迭代。我使用typedef“制作”了一个迭代器:
typedef std::vector<Object*>::iterator Cursor;
我的问题是,当它到达向量的开头时,这个函数似乎崩溃了。我有以下代码:
void InsertFunc(Cursor& it, Object& o) {
vec_.insert(it, o);
--it;
for (; it >= vec_.begin(); --it) {
if ((*it)->type() == Object::SomeType) {
do_something
} else {
do_something_else
}
}
std::cout << "Insertion succes!" << std::endl;
}
我已经测试过了,我确定该函数已经到达向量的开头,但是程序刚刚终止并且消息“Insertion succes!”永远不会打印。知道为什么吗?
答案 0 :(得分:7)
如果由于重新分配的增加而必须在内存中移动元素,那么insert
可能会使您的迭代器失效。
您可以从插入调用本身获取一个新的有效迭代器:
it = vec_.insert(it, o);
离开你。
如果新元素已经 --it
,则您的以下行begin()
将导致失败;你刚刚开始迭代了。说实话,我完全重新考虑了这个功能的逻辑。
答案 1 :(得分:0)
首先,对vec.insert( it, o )
的调用可能会使it
无效。
你想要:
it = vec.insert( it, o );
(返回插入元素的迭代器)。
其次,如果it
等于vec.begin()
,则以下--it
是非法的。
第三,如果it >= vec.begin()
永远不会是假的,除非
代码包含未定义的行为:迭代器的有效范围
是it >= vec.begin() && it < vec.end()
。 (但我们通常会尝试
避免比较迭代器上的不等式,因为没有
所有迭代器都支持它们。
你可能想要的是:
void InsertFunc( Cursor& it, Object const& o )
{
it = vec.insert( it, o );
while ( it != vec.begin() ) {
-- it;
// ...
}
}
当在一个范围内向后迭代时,通常的解决方案是
使用while
,减少位于顶部。
或者,您可以使用反向迭代器:
void InsertFunc( Cursor& it, Object const& o )
{
typedef std::vector<Object>::reverse_iterator RCursor;
it = vec.insert( it, o );
for (RCursor rit = RCursor(it); rit != vec.rend(); ++ rit ) {
// ...
}
}
(遗憾的是,似乎没有make_reverse
功能。然而,写起来并不难。)