2016-12-21 21 views
16

Miałem wrażenie, że nie można użyć erase na const iterator. Sprawdź this code.
Dlaczego poniższy kod się kompiluje (C++ 11, gcc)?Dlaczego const_iterator może być używany ze std :: map :: erase

long getMax(const bool get_new) 
{ 
    long max_val=0; 

    TO now=getNow(); 

    map<TO, long>& m=get_new?m_new:m_old; 

    for(auto it=m.cbegin(); it !=m.cend()) 
    { 
     if(now.compareTime((*it).first)<lookback) 
     { 
      max_val=max(max_val, 
         (*it).second); 
      ++it; 
     } 
     else 
     { 
      it=m.erase(it); 
     } 
    } 

    return max_val; 
} 

Sam map nie jest stała, ale mój zrozumienia jest to, że const iterator powinien uczynić to niepowodzeniem.

Odpowiedz

15

Zachowanie się zmieniło z C++ 11; std::map::erase przyjmuje const_iterator jako jego parametr.

void erase(iterator pos);   // (until C++11) 
iterator erase(const_iterator pos); // (since C++11) 
iterator erase(iterator pos);  // (since C++17) 

Dla std::map::erase, przekazany iterator jest tylko używane jako miejsca, w którym element zostanie usunięty, nie do modyfikowania elementu przez nią. Oznacza to, że const_iterator będzie w porządku. Przed C++ 11 wsparcie dla const_iterator nie było zbyt dobre, ale sytuacja zmieniła się z C++ 11. Powinieneś teraz użyć const_iterator zamiast iterator, jeśli to możliwe.

9

Pozycje są niezależne od ich stałego dostępu. Było (jest?) Dość powszechne, że funkcje wykonujące wyszukiwanie zwracają const_iterator, ponieważ w rzeczywistości nie zmieniają w ogóle kontenera. Jednakże pożądane jest zastosowanie uzyskanej pozycji do mutacji sekwencji, np. Do insert() elementu w odpowiednim położeniu lub do umieszczonego elementu. W rezultacie pojemnik został rozszerzony, aby wspierać użycie funkcji const_iterator z operacjami mutowania. Wydaje się, że odpowiedni dokument to N2350. Nie jestem pewien, czy ten dokument jest najnowszą wersją.

Powiązane problemy