擦除从一个std ::向量,而为每个?

迭代的正确方法是使用迭代器。 但是,我认为通过擦除,迭代器是无效的。

基本上我想要做的是:

for(iterator it = begin; it != end; ++it) { if(it->somecondition() ) { erase it } } 

我怎么能没有v [i]方法做到这一点?

谢谢

 struct RemoveTimedEvent { bool operator()(const AguiTimedEvent& pX, AguiWidgetBase* widget) const { return pX.getCaller() == widget; } }; void AguiWidgetContainer::clearTimedEvents( AguiWidgetBase* widget ) { std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), RemoveTimedEvent()); timedEvents.erase(it, timedEvents.end()); } 

erase()返回一个新的迭代器:

 for(iterator it = begin; it != end(container) /* !!! */;) { if (it->somecondition()) { it = vec.erase(it); // Returns the new iterator to continue from. } else { ++it; } } 

请注意,我们不能再将其与预先计算的结果进行比较,因为我们可能会将其清除并因此使其无效。 我们必须明确地明确每一次。

一个更好的方法可能是组合std::remove_iferase() 。 你从O(N 2 )(每个元素都被擦除并移动)到O(N):

 iterator it = std::remove_if(begin, end, pred); vec.erase(it, vec.end()); 

pred是你的去除谓词,比如:

 struct predicate // do choose a better name { bool operator()(const T& pX) const // replace T with your type { return pX.shouldIBeRemoved(); } }; iterator it = std::remove_if(begin, end, predicate()); vec.erase(it, vec.end()); 

在你的情况下,你可以使它相当一般:

 class remove_by_caller { public: remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {} // if every thing that has getCaller has a base, use that instead template <typename T> // for now a template bool operator()(const T& pX) const { return pX.getCaller() == mWidget; } private: AguiWidgetBase* mWidget; }; std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget)); timedEvents.erase(it, timedEvents.end()); 

注意lambda的存在来简化这个过程,无论是在Boost和C ++ 11中。