從 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中文網其他相關文章!