Rumah >pembangunan bahagian belakang >C++ >Adakah Memadamkan Elemen daripada `std::set` Semasa Gelagat Ditentukan Lelaran dalam C atau Khusus Pelaksanaan?

Adakah Memadamkan Elemen daripada `std::set` Semasa Gelagat Ditentukan Lelaran dalam C atau Khusus Pelaksanaan?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-04 08:30:14596semak imbas

Is Deleting Elements from a `std::set` During Iteration Defined Behavior in C   or Implementation-Specific?

Memadamkan Elemen daripada std::set Semasa Lelaran: Implikasi Pelaksanaan

Lelaran melalui set semasa mengalih keluar elemen boleh menimbulkan cabaran, kerana operasi berpotensi membatalkan lelaran. Dalam konteks ini, persoalan timbul: adakah tingkah laku ini ditakrifkan oleh standard C atau adakah ia khusus pelaksanaan?

Ketergantungan Pelaksanaan

Mengikut piawaian C (23.1 .2.8), pemasukan elemen ke dalam set tidak boleh menjejaskan iterator atau rujukan kepada bekas, manakala elemen memadamkan hanya akan membatalkan iterator dan rujukan kepada elemen yang dipadam. Walau bagaimanapun, gelagat iterator semasa operasi pemadaman tidak dinyatakan secara eksplisit, membiarkannya terbuka kepada keputusan khusus pelaksanaan.

Pelaksanaan GCC

Dalam kod contoh yang disediakan, menggunakan GCC 4.3.3 pada Ubuntu 10.04, memadamkan elemen daripada set semasa lelaran tidak membatalkan lelaran. Ini menunjukkan bahawa pelaksanaan GCC mengikut pendekatan yang lebih santai, membenarkan penggunaan berterusan iterator selepas dipadamkan.

Penyelesaian Mematuhi

Untuk memastikan pematuhan standard, pendekatan yang berbeza diperlukan. Satu penyelesaian biasa ialah membuat salinan lelaran sebelum memadamkan elemen:

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        numbers.erase(it++);
    }
    else {
        ++it;
    }
}

Dalam kes ini, kenaikan postfix (it ) menghantar kedudukan lama kepada fungsi erase() sambil melompat ke elemen seterusnya. Kenaikan postfix diutamakan di sini kerana ia mengelakkan potensi isu kenaikan dua kali yang boleh berlaku dengan kenaikan awalan (apabila keadaannya palsu).

C 11 Update

Dengan kedatangan C 11, penyelesaian yang lebih elegan tersedia. Fungsi erase() kini mengembalikan iterator kepada elemen yang mengikuti elemen terakhir yang dialih keluar (atau set::end jika elemen terakhir telah dipadamkan). Ini membolehkan pelaksanaan yang lebih ringkas:

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        it = numbers.erase(it);
    }
    else {
        ++it;
    }
}

Atas ialah kandungan terperinci Adakah Memadamkan Elemen daripada `std::set` Semasa Gelagat Ditentukan Lelaran dalam C atau Khusus Pelaksanaan?. 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