Iteratorler, STL konteynerlerindeki elemanlara işaret eden nesnelerdir ve göstericilere benzer. Herhangi bir konteynere (vector, list, map vb.) elemanlara birleşik erişim yolu sağlarlar. Farklı türlerde iteratorler vardır:
Iteratorlerin ömrüne dikkat etmek önemlidir:
Örnek:
std::vector<int> v = {1,2,3,4,5}; for (auto it = v.begin(); it != v.end(); ++it) { if (*it == 3) { // 3 değerine sahip elemanı kaldırıyoruz it = v.erase(it); // erase, bir sonraki elemanın iteratorunu döndürür --it; // gerekirse iteratoru ayarlayın } }
Soru: std::vector::insert çağrıldığında iteratorler geçersiz hale gelir mi?
Sık Yanıt: Hayır, sadece son aralığın dışına ekleme yapıldığında.
Doğru Yanıt: Ekleme pozisyonuna eşit veya daha sonraki tüm iteratorler ve referanslar geçersiz olur, eğer konteynerin kapasitesi artarsa. Eğer kapasite yeterliyse — geçersizlik, sadece ekleme noktasından sonraki aralıktaki iteratorlerde olur.
Örnek:
std::vector<int> v = {1,2,3}; auto it = v.begin() + 1; v.insert(v.begin(), 0); // burada it geçersiz hale gelebilir!
Hikaye: std::vector üzerinde iterasyon için işaretçiler kullanıldı ve push_back'ten sonra iterasyon geçersiz işaretçiler üzerinde devam etti, bu durum uygulamanın çökmesine yol açtı.
Hikaye: Geliştirici, for(auto it : list) döngüsünde erase ile std::list elemanlarını kaldırdı, ancak döndürülen erase iteratorunu kullanmadı, bu nedenle iterasyon bazı elemanları atlayarak tüm gerekli elemanları silmedi.
Hikaye: Kodda std::map kullanıldı ve bir anahtar ile erase işleminden sonra iterator kaldırılan elemana bağlı kaldı (tanımsız davranış) — bu, sonraki erişimlerde rastgele hatalara neden oldu.