2013-04-29 5 views
7

Nach den meisten C++ Referenzen, zum Beispiel cplusplus.com, forward iterators müssen nicht zuweisbar sein (ich meine, von einem lvalue deferenziert). Doch für einige STL-Algorithmen, die Werte schreiben müssen, zum Beispiel std::fill (auch std::generate etc.), die Spezifikation verwendet vorwärts Iterator:STL füllen und weiterleiten Iterator

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val); 

während die äquivalente Verhalten lvalue dereferenzieren erfordert:

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val) 
{ 
    while (first != last) { 
    *first = val; 
    ++first; 
    } 
} 

Es verwendet also einen veränderlichen Vorwärtsiterator mit einem einzigen Durchlauf.

Nun die Fragen sind:

(1) Warum es nicht machen deutlich, dass die Vorwärts-Iteratoren in diesen Fällen wandelbar sind?

(2) Update: Ich fand die folgende Frage dumm: Ich habe vorübergehend vergessen, dass Ausgabe-Iteratoren Gleichheitsvergleich nicht unterstützen müssen. Die obige Frage bleibt trotzdem bestehen.

Warum Forward-Iteratoren anstelle von Ausgabe-Iteratoren für std::fill, std::generate usw. verwenden, während sie eigentlich nicht mehrere Durchgänge benötigen? (std::copy braucht nur Ausgang Iteratoren, zum Beispiel. Was der Grund ist?)

+0

'Vorwärts-Iteratoren müssen nicht zuweisbar sein', wie haben Sie das festgestellt? Ich bin mir ziemlich sicher, dass sie zuweisbar sind. –

+0

@JesseGood Für praktische Zwecke sind sie fast immer zuweisbar, aber wenn Sie die Referenz http://cplusplus.com/reference/iterator/ForwardIterator/?kw=forward%20iterator lesen, ist es nicht. – 4ae1e1

+1

@JesseGood Ich fand auch das auf SO: http://StackOverflow.com/Questions/14058642/are-forward-iterators-output-iterators – 4ae1e1

Antwort

5

Von der Signatur

template <class ForwardIterator, class T> 
void fill (ForwardIterator first, ForwardIterator last, const T& val); 

kann man nicht ableiten, dass ForwardIterator ein Iterator in forward iterator beschrieben ist. wenn Sie den Parameter Beschreibung jedoch zu lesen, werden Sie feststellen, dass first und last

Forward Iterators zu den Anfangs- und Endpositionen in einer Folge von Elementen sein muss , die einen Wert vom Typ T zugewiesen unterstützen werden.

(Schwerpunkt von mir). Ein Forward-Iterator, der nicht mehr erfüllt als der Forward-Iterator, ist also kein gültiges Argument.

+0

Ja, das ist ein guter Punkt. Aber die Unterschrift ist vom Standard her schwierig. – 4ae1e1

+0

Die Alternative wäre, einen neuen Namen für Vorwärts-Iteratoren einzuführen, die die Zuordnung zu dem Element, auf das gezeigt wird, unterstützen. – Oswald

1

Es scheint mir nicht sonderlich merkwürdig, da die Spezifikation für fill ist, dass der (dereferenzierte) Iterator von T zuweisbar ist. Ein Ausgabe-Iterator wird nicht ausreichen, da er nicht vergleichbar ist, um das Ende des Bereichs zu bestimmen. Daher wurde ein forward_iterator mit Anforderungen ausgewählt.

Sie werden feststellen, dass fill_ndie Ausgabe-Iteratoren verwendet, da kein Iteratorvergleich erforderlich ist, um das Ende der zu füllenden Sequenz zu bestimmen.

+0

Ich denke, der Punkt von OP ist, dass das Konzept des Vorwärts-Iterators * erforderlich *, aber nicht * ausreichend ist, um die Anforderungen für den Argumenttyp zu spezifizieren. Das gleiche würde für "Ausgabe-Iterator" gelten; Nur wenn wir verlangen, dass das Argument * * * * ist, erhalten wir die korrekte Semantik. Anders gesagt gibt es Vorwärtsiteratoren, auf denen 'std :: fill' nicht aufgerufen werden kann. –

Verwandte Themen