Soru Const yineleyiciler hala C ++ 14'de kötüler mi?


Scott Mayers'ın "Etkin STL" maddesinin 26. maddesi "Prefer" olarak etiketlendi iterator için const_iterator, reverse_iterator ve const reverse iterator".

Muhakeme, bazı şekillerde insert() ve erase() tam olarak gerektirir iterator ve diğer türlerden dönüştürmek sıkıcı ve hataya eğilimlidir. Ayrıca, karşılaştırma iterator ve const_iterator STL uygulamasına bağlı olarak sorunlu olabilir.

Kitap 2001'de piyasaya sürüldü. Madde 26'daki tavsiye hala mevcut gcc durumuyla geçerli mi?


18
2017-09-11 09:09


Menşei


Tabii ki insert ve erase const olmayan iterator: Verileri değiştiriyorlar, böylece const veri kötü bir fikir olurdu. - gexicide
@gexicide: Yanlış. Eğer arayabilirsen erase, yine de konteynere değişken erişiminiz var. Ve bu nedenle, C ++ 11 değişti erase ve insert almak için fonksiyonlar const_iterators (iterators her zaman const_ varyantı). - Xeo
@ Xeo: Doğru, benim hatam. Temizlediğin için teşekkürler. - gexicide
OP için: Bu 3 yıl önce zaten düzeltildi. :) "Etkili STL" modası geçmiş. - Xeo
Scott Myers bir C ++ 11 / C ++ 14 sürümü ile çıkıyor Etkili Programlama RSN. Bu, burada yeni bir fikir verebilir. - emsr


Cevaplar:


C ++ 14 standardı (N3936) bunu garanti eder. iterator ve const_iterator serbestçe karşılaştırılabilirdir (§23.2.1 [container.requirements.general] / p7):

İfadelerde

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j

nerede i ve j kapsayıcının nesnelerini belirtmek iterator tipi,   ya da her ikisi de kapsayıcının bir nesnesiyle değiştirilebilir.    const_iterator hiçbir değişiklik olmadan aynı öğeye başvuran tür   semantik.

Ek olarak, kapsayıcı üye işlevleri const_iterator C ++ 11 (§C.2.13 [diff.cpp03.containers] 'dan itibaren parametreler - etiketinden çıkarılabileceği gibi, bu C ++ 03'ten bir değişikliktir):

Değişiklik: İmza değişiklikleri: iterator için const_iterator parametreler

gerekçe: Aşırı değerlendirme. Etkileri: Aşağıdaki üye fonksiyonlarının imzaları bir iterator almaya   bir const_iterator:

  • insert(iter, val) için vector, deque, list, set, multiset, map, multimap
  • insert(pos, beg, end) için vector, deque, list, forward_list
  • erase(iter) forset,multiset,harita,multimap`
  • erase(begin, end) forset,multiset,harita,multimap`
  • her türlü list::splice
  • her türlü list::merge

Kapsayıcı gereksinimleri, const yineleyicileri almak için benzer şekilde değiştirildi. Ek olarak, alttaki yineleyiciyi bir std::reverse_iterator onun aracılığıyla .base() üye işlevi. Dolayısıyla, soruda belirtilen kaygıların hiçbiri uygun bir derleyicide bir sorun olmamalıdır.


18
2017-09-11 09:31



Bunun açıkça C ++ 03 -> C ++ 11'den bir değişiklik olduğunu belirtmelisiniz. - Xeo
.Base sahip ters yineleyiciler hakkında bir not da iyi olurdu. - Puppy


Yaklaşmanın 13. Maddesinden de görülebileceği gibi tavsiye tersine çevrildi. Etkili Modern C ++ başlıklı:

Const_iterators öğesini yineleyicilere tercih et

Nedeni C ++ 11 ve C + + 14, birkaç tweaks eklemek const_iterators çok daha pratik:

C ++ 11 ekliyor

  • üye işlevleri cbegin() ve cend() Tüm Standart Kitaplık kapları için (ve onların ters meslektaşları)
  • pozisyonları tanımlamak için yineleyicileri kullanan üye işlevleri (ör. insert(), erase()) şimdi bir al const_iterator yerine iterator

C ++ 14 üye olmayan ekleyerek tamamlar cbegin() ve cend()  (ve onların ters meslektaşları)


7
2017-09-13 11:31