2010-01-18 12 views
10

'da nasıl kaldırılır C++ 'da yeni. Kodlayıcıların bunu nasıl yaptığını bilmek isterim.set <int> setindeki tüm tamsayılar C++

Elimde ne:

set<int> s; 
s.insert(1); 
s.insert(2); 
s.insert(3); 
s.insert(4); 
s.insert(5); 

for(set<int>::iterator itr = s.begin(); itr != s.end(); ++itr){ 
if (!(*itr % 2)) 
    s.erase(itr); 
} 

ve tabii

, bu işe yaramaz. çünkü silinir sonra itr artırılır. , elemanın setten çıkarılmasından sonra her zaman setin başlangıcına işaret etmesi anlamına mı geliyor?

cevap

16
for(set<int>::iterator itr = s.begin(); itr != s.end();){ 
    if (!(*itr % 2)) 
     s.erase(itr++); 

    else ++itr; 
} 

etkili STL Scott Myers iyi yolu kullanmaktır

+0

Kodda fazladan parantez var. – qba

+0

itr ++ neden silme fonksiyonuna izin verilir, fakat dışarıda değil mi? – Quincy

+5

'itr ++' dışarısı için izin verilir, ancak '+ + ', değeri kullanılmadığında genel olarak tercih edilir, çünkü herkesin yaptığı her seferinde zamanın yorucu olmasının nedenleri ;-) Bu durumda, daha iyi olabilir. olağan iyi uygulamaları görmezden gel ve 'itr ++' yaz, çünkü her iki durumda da aynı olsa, kod biraz daha yumuşak okur. –

11

std :: set öğesinden bir öğenin silinmesi, yalnızca o öğeye işaret eden yineleyicileri geçersiz kılar.

Hedef öğeyi silmeden önce bir sonraki öğeye yineleyici alın.

8

Başa dönmeniz gerekmez. set::erase sadece silinmeye maddesine bakın yineleyiciler geçersiz kılmaktadır, bu yüzden sadece silmeden önce yineleyici ve artışı kopyalamak gerekir:

for(set<int>::iterator itr = s.begin(); itr != s.end();) 
{ 
    set<int>::iterator here = itr++; 
    if (!(*here % 2)) 
     s.erase(here); 
} 
+0

Tamam, pes ediyorum. Hata nedir? –

+1

Yanılıyordum, ilk unsuru atladığınızı sanıyordum. Yorumumu ve reddini geri aldım. –

-1

tarafından remove_if ve kombinasyonu Bu yararlı olacaktır

s.erase(remove_if(s.begin(), s.end(), evenOddFunctor), s.end()) 

silmek http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove

Ayrıca Scott meyers

Edit

tarafından etkili STL bakınız: my çözüm i silme değilim yanlış olmasına rağmen. Benim gibi birileri için iyi bir öğrenme olabilir değişmeyen/immutable yineleyiciler hakkında değil

+6

'remove_if',' operator * 'in const olmayan bir değer döndürmesini gerektirir. std :: set, her zaman sipariş edildiğini zorlar; const olmayan bir lvalue 'std :: set :: operator * 'den döndürülmesi bu garantiyi bozar. Bu nedenle 'std :: remove_if()' 'std :: set :: iterator's – MSalters

+0

almaz. Teşekkürler diyorum ki –

+5

Bu gerçekten yardımcı oldu. Bunu remove_if ile yapmaya çalışıyorum ve bu bana sorunun ne olduğunu anlattı. Teşekkürler. –