Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mengalih Keluar Elemen dengan Selamat daripada `std::vector` Semasa Mengulang?

Bagaimana untuk Mengalih Keluar Elemen dengan Selamat daripada `std::vector` Semasa Mengulang?

DDD
DDDasal
2024-11-01 20:27:02169semak imbas

How to Safely Remove Elements from a `std::vector` While Iterating?

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn