2016-01-25 17 views
7

Ich habe gerade den folgenden Code geschrieben, und war sehr überrascht, dass es nicht kompilieren lässt:Warum werden Rückwärts-Iteratoren nicht unterstützt?

std::deque<int> container; 
// filling the container... 
for (auto it = container.rbegin(); it != container.rend(); ++it) 
    if (*it == 5) 
    { 
     container.erase(it); 
     break; 
    } 

Wie Sie sehen können, habe ich das letzte Element eine bestimmte Kriterien übereinstimmen, wenn überhaupt löschen möchten.

Der Fehler

keine passende Funktion für Aufruf std :: deque :: erase (std :: reverse_iterator ist ...

Zuerst glaubte ich nicht, es war ., die durch den Reverse-Iterator, aber das ist in der Tat der Fall, da rbegin/rend mit dem ersetzen begin/end es löst

So, 2 Fragen:

  1. Warum wird dies nicht unterstützt? Ist es nur eines dieser kleinen Dinge, die das C++ - Komitee vergessen hat, in den Standard aufzunehmen, oder gibt es eine Rechtfertigung dafür, dass diese Überladung fehlt?
  2. Was ist die eleganteste Art zu tun, was ich will? Bleibe ich beim Iterieren nach Index?
+4

Ich denke, Ihre Antwort ist hier: http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse- Iterator –

+0

Sind 'm_container' und' container', die gleichen? – ZDF

+0

@ ZDF: ja, natürlich. Fixed. –

Antwort

1

Ich kann nicht auf "Warum" Frage antworten, aber um das "Wie" zu beantworten - Sie sollten base() auf Ihrem Iterator aufrufen. Es wird einen richtigen Vorwärts-Iterator zurückgeben.

Beachten Sie dabei die Beziehung zwischen Reverse- und Forward-Iteratoren. es könnte zunächst verwirrend sein, aber eigentlich ziemlich einfach. Wenn Sie ein std::vector enthalten die folgenden Elemente haben:

1, 2, 3, 4, 5 

Und Sie haben eine reverse_iterator rit, die auf dereferencing Ihnen 3 gibt, dann wird *(rit.base) gleich 4 sein, zu sehen, warum, nur daran erinnern, dass in normalen Iteratoren begin() ist dereferencable, aber end() ist nicht. In umgekehrten Iteratoren muss die Eigenschaft die gleiche sein - rbegin() muss dereferencible sein, aber rend() sollte nicht - d. H. Sollte über den Anfang des Containers zeigen.

Da per definitionem ist rend.base() die gleiche wie begin() (weil Rend können alle oben als reverse_iterator(begin()), die einzige Art und Weise aufgebaut sein, halten können, ist, wenn rend.base() wird ein nächstes rechtes Element auf den einen über den Anfang zurückkehren - begin() Es ist leicht zu sehen, dass die gleiche Symmetrie für rend() gilt.

+0

Downvoted die Antwort, weil Sie 'reverse_iterator :: base()' nicht einfach an den 'er übergeben können ase-Methode. –

+0

@VioletGiraffe, warum? – SergeyA

+0

Weil es das falsche Element löschen würde! Der Iterator muss zuerst um 1 angepasst werden. –

Verwandte Themen