Lelaran dan Pemadaman daripada std::vector
Pendekatan yang disyorkan untuk lelaran melalui std::vector ialah menggunakan iterator. Walau bagaimanapun, pemadaman elemen semasa lelaran boleh membatalkan lelaran.
Untuk menangani isu ini, adalah penting untuk mengubah suai tugasan lelaran selepas memadamkan elemen, seperti yang ditunjukkan di bawah:
<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>
Adalah penting untuk ambil perhatian bahawa hujung bekas hendaklah dikira semula setiap kali selepas memadamkan elemen.
Alternatif yang lebih cekap ialah menggabungkan std::remove_if dan erase():
<code class="cpp">iterator it = std::remove_if(begin, end, pred); vec.erase(it, vec.end());</code>
Pendekatan ini menukar kerumitan masa daripada O(N^2) kepada O(N). Berikut ialah contoh predikat untuk mengalih keluar elemen:
<code class="cpp">struct predicate { bool operator()(const T& pX) const { return pX.shouldIBeRemoved(); } };</code>
Untuk kes khusus anda, anda boleh menggunakan pendekatan yang lebih generik:
<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>
Menggunakan pendekatan ini:
<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>
Selain itu, ungkapan lambda boleh memudahkan proses ini, seperti yang disokong dalam kedua-dua Boost dan C 11.
Atas ialah kandungan terperinci Bagaimana untuk Mengalih Keluar Elemen dengan Selamat daripada `std::vector` Semasa Mengulang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!