在C ++中,是否存在允许我在以下for循环中向其添加元素的数据结构?
(我使用list
作为例子,因为这是我到目前为止所尝试过的。)
list<Elem> elems;
// fill elems with some Elems;
for(list<Elem>::iterator it=elems.begin(); it!=elems.end();) {
// ...
if(condition)
it = elems.erase(it);
else {
Elem elem;
it = elems.push_back(elem);
}
}
的后续问题
答案 0 :(得分:3)
This answer on StackOverflow概述了所有标准容器的行为。
在插入或擦除时不会使迭代器无效的容器是list
,set
,multiset
,map
和multimap
。当然这不包括被删除的迭代器。
答案 1 :(得分:1)
是的,list
允许你这样做..正如我在其他答案的评论中所说的那样......
答案 2 :(得分:1)
根据请求编写此内容。
PS:这是从矢量中删除元素的后续问题
这是你提问的一个令人不安的模式。
说真的,在迭代容器时修改容器是坏事。很难做对。在性能方面,它通常不会为您节省太多。很少(除了在有限的情况下,有一个标准库算法完全适合您的需求)更容易表达。如果你做错了,它的性能会非常昂贵。如果你做错了,那么在程序正确性方面可能会非常昂贵,这比其他任何东西都重要得多。
如果涉及线程,则会出现指数恶化。 Java有一个专用的异常类型,专门针对某些可能在您尝试时出错的事情。在C ++中你不是那么幸运;类似的问题可能无法检测到。
只需编写产生最终结果的代码,然后替换原始容器。唯一可以真正减缓这种情况的是“实例复制成本很高”,在这种情况下,您应该已经使用了一层间接来处理问题(假设它真的很重要)。
list<Elem> original;
// fill elems with some Elems;
list<Elem> modified;
for (
list<Elem>::iterator it = original.begin(), end = original.end();
it != end; ++it
) {
if (something()) {
modified.push_back(*it);
} else if (something_else()) {
modified.push_back(Elem()); // for example
}
// else, 'erase' the element by just not putting anything into 'modified'
// Or we could do whatever other combination of things,
// maybe insert more than one
}
std::swap(original, modified);
答案 3 :(得分:0)
有several containers支持插入而不会使迭代器失效。在你的代码中,你有正确的删除案例,但我相信你过度思考插入案例。试试这个:
else {
Elem elem;
elems.push_back(elems);
++it;
}
您在给定示例中使用了list
,因此您知道push_back
来电不会使it
无效。因此,您可以简单地增加它以到达下一个元素。您只需要在removing elements时小心,因为您无法递增指向不再存在的位置的迭代器。