Sind ForwardIterators als OutputIterators erforderlich? Meine aktuelle STL-Implementierung (VS2012) leitet forward_iterator_tag
sowohl von input_iterator_tag
als auch output_iterator_tag
ab, aber ich kann diese Anforderung nicht im Standard [N3485] finden.Sind Forward-Iteratoren Output-Iteratoren?
Antwort
In C++ 11, Nein, Vorwärts-Iteratoren müssen nicht ausgegeben werden Iteratoren. Die Anforderungen des Ausgabe-Iterators sind wie eine zusätzliche Menge von Anforderungen, die ein Iterator haben kann, unabhängig von den übrigen Iteratoranforderungen, die er erfüllt. Vorwärts-Iteratoren sind nur Eingangs Iteratoren sein erforderlich (§24.2.5/1):
A-Klasse oder Zeigertyp X erfüllt die Anforderungen eines Vorwärts-Iterator, wenn:
- X erfüllt die Anforderungen der ein InputIterator
- ...
In der Tat, ein vorwärts-Iterator erfüllt die Output-Iterator Anforderungen nur, wenn es ein veränderliches Iterator zu einem Sequen ist Kopie der zuweisbaren Typen †.
† oder ein konstanter Iterator für eine Sequenz von Typen mit operator=(...) const
definiert mit veränderbaren Elementen.
Mehr zu dem Punkt, werden die Iterator-Tags speziell durch den Standard als (§24.4.3/2) definiert:
Wie Sie sehen können, forward_iterator_tag
nur von input_iterator_tag
erben sollte.
In C++ 03 wird darauf hingewiesen, dass zukunfts Iteratoren die Anforderungen der Eingangs- und Ausgangs Iteratoren erfüllen:
Vorwärts-Iteratoren erfüllen alle Anforderungen an die Eingangs- und Ausgangs Iteratoren und kann verwendet werden, wann immer eine Art angegeben ist.
Aber dies wird dann im folgenden Absatz widersprochen, die besagen, dass ein konstanter Vorwärts Iterator würde nicht die Anforderungen für die Ausgabe Iteratoren erfüllen:
Neben seiner Kategorie, einer nach vorn, bidirektionale oder Random-Access-Iterator kann auch veränderbar oder konstant sein, je nachdem, ob das Ergebnis des Ausdrucks * i sich als Referenz oder als Referenz auf eine Konstante verhält. Konstante Iteratoren erfüllen nicht die Anforderungen für Ausgabe-Iteratoren, und das Ergebnis des Ausdrucks * i (für konstanten Iterator i) kann nicht in einem Ausdruck verwendet werden, für den ein lvalue erforderlich ist.
Die Definition der Iterator-Tags ist jedoch identisch mit der in C++ 11. Es gab eine defect report für diese widersprüchliche Formulierung, aber es wurde als kein Fehler geschlossen, weil das erste Zitat im "einleitenden Text" des Abschnitts ist und würde wahrscheinlich in der Zukunft (was es war) umformuliert werden.
Die SGI definition of a forward iterator als Verfeinerung der beiden Eingangs- und Ausgangs Iteratoren (Dank in den Kommentaren @BenVoigt) gegeben.
Dennoch, wenn wir uns die implementation of the iterator tags ansehen, finden wir, dass forward_iterator_tag
immer noch nur von input_iterator_tag
erbt.
Sieht aus wie dies ein Bereich von ziemlich viel Verwirrung in der Vergangenheit gewesen ist, aber wenn VS2012 forward_iterator_tag
als Erben von beiden output_
ist die Definition - und input_iterator_tag
, kann ich nur annehmen, dass es ein Fehler ist.
- 1. Aktionen sind zustandslos, aber Controller sind zustandslos?
- 2. Warum sind diese Standardparameter so definiert, wie sie sind?
- 3. Pandas Timestamp-Komponenten - einige sind Eigenschaften und einige sind Methoden?
- 4. Obwohl magic_quotes ausgeschaltet sind, sind immer noch Strings entgangen?
- 5. Sind alle Funktionen "noexcept", wenn Ausnahmen deaktiviert sind?
- 6. NSLayoutConstraint Stellen sind durchweg nil während andere Steckdosen sind nicht
- 7. Was sind die verschiedenen Techniken sind megamorphic Aufrufstellen effizienter
- 8. Zwei .NET-Objekte, die gleich sind nicht sagen, sie sind
- 9. Wo sind CAD-Apps geschrieben und wie sind sie organisiert?
- 10. Warum sind die Namenskonventionen von Jest so, wie sie sind?
- 11. Sind die Objekte einer Combobox leer, wenn sie leer sind?
- 12. Sind Callbacks immer asynchron?
- 13. Sind Meta-Schlüsselwörter empfindlich?
- 14. Sind Java Filter Singleton
- 15. MATLAB Beispiele sind fehlgeschlagen
- 16. Sind Generatoren Threadssafe?
- 17. Was sind Konzepte?
- 18. Was sind NDF-Dateien?
- 19. Sind HTTPS-Header verschlüsselt?
- 20. Warum sind Abhängigkeitseigenschaften "statisch"?
- 21. Was sind WPF-Vorschauereignisse?
- 22. Was sind Futures?
- 23. Sind + =, | =, & = etc atomar?
- 24. AudioQueue-Beispielwerte sind falsch
- 25. Sind Functor-Instanzen einzigartig?
- 26. Was sind current_user_can() Funktionsparameter?
- 27. Was sind Iteratoren, C++?
- 28. Wo sind JDBC4-Anmerkungen?
- 29. Was sind Optionen + FolgenSymLinks?
- 30. Sind HATEOAS-Links anklickbar?
Aber beachten Sie, dass diese von der SGI-Definition, anders zu sein scheint, wo die Dokumentation sagt, dass ForwardIterator „eine Verfeinerung von InputIterator und OutputIterator“ ist, das heißt, es existiert ForwardInputIterator und ForwardOutputIterator aber nicht einfach ForwardIterator kann das Konzept nicht allein stehen. –
@BenVoigt Es scheint, dass dies zwischen C++ 03 und C++ 11 geändert wurde. Edit: Warte, eigentlich ist es verwirrend. –
@sftrabbit: Danke, dass du das geklärt hast. Was ist nun die kanonische Methode, einen Iterator sowohl als vorwärts als auch als Ausgabe zu kennzeichnen? (Führen Sie einfach ein neues privates Tag ein, das von beiden erbt, oder gibt es einen anderen Weg?) – MFH