2012-12-27 14 views
7

Wie definiert man Vorwärtsausgabe-Iteratoren in C++ 11 auf kanonische Weise?Kanonische Methode zum Definieren von Vorwärtsausgabe-Iterator

Gemäß dem Standard ist ein forward_iterator nur ein input_iterator. So erstreckt sich die entsprechende forward_iterator_tag nur input_iterator_tag. Wenn wir std::iterator verwenden, um unsere Iteratoren zu definieren, welches Tag verwenden wir für einen Forward-Output-Iterator?

Kann man ein privates Tag definieren, das sowohl als auch output_iterator_tag erweitert oder gibt es eine bessere Lösung?

+0

Erben von beiden wird tun –

+0

Als eine Nebenfrage: Weiß jemand, ob diese veränderlichen Iterator-Tags für die Standard-Bibliothek berücksichtigt wurden? Und wenn ja, warum wurden sie nicht einbezogen? –

Antwort

6

Die kanonische Sache ist, nur von std::iterator<std::forward_iterator_tag, T> zu erben. Iteratoren haben nur eine Kategorie.

Der Standard enthält keine Algorithmen (oder andere Verwendungen) für einen Ausgabe-Iterator, der auch ein Vorwärts-Iterator ist. Alle Verwendungen von Ausgabe-Iteratoren im Standard erfordern nur Single-Pass.

Stattdessen hat der Standard die Idee von veränderbaren vs unveränderlichen Iteratoren der Kategorien forward/bidi/randomaccess. Alle Algorithmen, die über Iteratoren schreiben müssen und die besser als Single-Pass sind, lesen auch dieselben Iteratoren durch, die sie schreiben. Dies ist std::remove, std::sort und andere Mutationsalgorithmen.

Der Unterschied zwischen veränderbaren und unveränderbaren Iteratoren wird nicht vom Iterator-Tag erkannt, sondern davon, ob die Zuweisungsausdrücke wohlgeformt sind. Wenn Sie zum Beispiel einen Iterator an std::sort übergeben, der unveränderlich ist, wird der Algorithmus trotzdem nicht kompiliert. Daher ist es im Allgemeinen nicht erforderlich, dass ein Eingabe-Iterator auch mit output_iterator_tag gekennzeichnet wird. Alle Algorithmen, die eine OutputIterator erfordern, funktionieren nur mit einer veränderbaren ForwardIterator, wiederum muss sie nicht mit output_iterator_tag getaggt werden.

Wenn Sie andere Anforderungen haben als die Standardalgorithmen, kann ich mir nicht sofort einen Grund vorstellen, warum Ihr Vorschlag für Ihre Iteratoren nicht funktioniert. Mutable Standard-Iteratoren werden jedoch nicht erkannt. Zum Beispiel std::deque<int>::iterator und int* haben Iterator Kategorie random_access_iterator_tag, nicht Ihr privates Tag und nichts mit output_iterator_tag zu tun. Es wäre also wahrscheinlich besser, wenn Sie Ihre eigene Traits-Klasse definieren, anstatt zu hoffen, die vorhandene iterator_traits::iterator_category an die gewünschten Informationen anzupassen.

+0

Danke! Das hat einiges geklärt. Am Ende bedeutet dies, dass unveränderliche Iteratoren const-Referenzen/Kopien des auf das Element verwiesenen Objekts zurückgeben, um die Zuweisung über die zurückgegebene Referenz zu verhindern, nicht wahr? – MFH

+1

@MFH: das stimmt. Unveränderliche Iteratoren über Container geben 'const T &' zurück (ich habe nicht überprüft, ob das tatsächlich erforderlich ist, oder ob sie stattdessen Proxies zurückgeben dürfen). Andere unveränderbare Iteratoren können alles, was in "T" konvertierbar ist, zurückgeben. –

Verwandte Themen