从 std::vector 迭代和擦除
迭代 std::vector 的推荐方法是使用迭代器。然而,在迭代时擦除元素可能会使迭代器失效。
要解决这个问题,在擦除元素后修改迭代器赋值至关重要,如下所示:
<code class="cpp">for (iterator it = begin; it != end(container) /* !!! */; ) { if (it->somecondition()) { it = vec.erase(it); // Returns the new iterator to continue from. } else { ++it; } }</code>
重要的是请注意,每次擦除元素后都应重新计算容器的末尾。
更有效的替代方案是将 std::remove_if 和 Erase() 结合起来:
<code class="cpp">iterator it = std::remove_if(begin, end, pred); vec.erase(it, vec.end());</code>
这种方法将时间复杂度从 O(N^2) 更改为 O(N)。以下是用于删除元素的谓词示例:
<code class="cpp">struct predicate { bool operator()(const T& pX) const { return pX.shouldIBeRemoved(); } };</code>
对于您的具体情况,您可以使用更通用的方法:
<code class="cpp">class remove_by_caller { public: remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {} template <typename T> bool operator()(const T& pX) const { return pX.getCaller() == mWidget; } private: AguiWidgetBase* mWidget; };</code>
使用此方法:
<code class="cpp">std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget)); timedEvents.erase(it, timedEvents.end());</code>
此外,lambda 表达式可以简化此过程,Boost 和 C 11 都支持。
以上是如何在迭代时安全地从 `std::vector` 中删除元素?的详细内容。更多信息请关注PHP中文网其他相关文章!