Die einfache Antwort ist, dass iterator
assoziierte Typen haben und ostream_iterator
konzeptionell gegen das Konzept eines Interators verstößt, indem ein value_type
benötigt wird, auch wenn es nicht notwendig ist. (Dies ist basicalt @ pts Antwort)
Was Sie vorschlagen, hängt mit der Idee hinter den neuen "transparenten Operatoren" zusammen, wie dem neuen std::plus<void>
. Welche bestehen in einer speziellen Instanziierung, deren Mitgliedsfunktion einen verzögerten Typ Abzug hat.
Es ist auch abwärtskompatibel, weil void
zu Beginn nicht sinnvoll ist. Außerdem ist der Parameter void
ebenfalls der Standardwert. Zum Beispiel template<T = void> struct std::plus{...}
ist die neue Deklaration.
Eine mögliche Implementierung eines transparenten ostream_iterator
Zurück von std::ostream_iterator
, ein wichtiger Test ist, ob wir es mit std::copy
arbeiten wollen, da std::ostream_iterator
normalerweise verwendet wird:
%Vor%
Die Technologie für eine transparente std::ostream_iterator
ist noch nicht da, denn das schlägt fehl:
%Vor%
Damit dies funktioniert, kann die Instanz void
explizit definiert werden. (Dies schließt die Antwort von @CashCow ab)
%Vor%
Jetzt funktioniert das:
%Vor%
Wenn wir das Standard-Komitee darüber hinaus dazu bringen, den Standardparameter void
zu verwenden (wie bei std::plus
):
template<class T = void, ...> struct ostream_iterator{...}
, wir könnten einen Schritt weiter gehen und den Parameter komplett weglassen:
%Vor%
Die Wurzel des Problems und ein möglicher Ausweg
Schließlich, meiner Meinung nach, könnte das Problem auch konzeptuell sein, in STL erwartet man, dass ein Iterator eine bestimmte value_type
assoziiert, auch wenn es nicht wie hier notwendig ist. In gewissem Sinne verletzt ostream_iterator
einige Konzepte eines Iterators.
Also gibt es zwei Dinge, die konzeptionell falsch sind in dieser Verwendung: 1) wenn man kopiert, erwartet man den Typ der Quelle zu kennen (Container value_type
) und Zieltypen 2) kopiert man überhaupt nichts !. Meiner Meinung nach gibt es in dieser typischen Anwendung einen doppelten Konstruktionsfehler. Es sollte ein std::send
vorhanden sein, das direkt mit einem Template shift <<
operators arbeitet, anstatt =
redirect auf <<
als ostream_iterator
zu setzen.
%Vor%
(Das letzte Argument sollte eine Art Sink
Konzept erfüllen).
** Verwenden Sie stattdessen std::accumulate
und eine mögliche Implementierung von
std::send
**
Aus konzeptioneller Sicht ist das Senden von Objekten an einen Stream eher eine "akkumulieren" Operation als ein Kopieroperator, also sollte std::accumulate
im Prinzip eine geeignetere Kandidat sein, außerdem brauchen wir kein "Ziel" Iteratoren dafür. Das Problem besteht darin, dass std::accumulate
keine Kopien von jedem Objekt erstellen möchte, das akkumuliert wird, also funktioniert das nicht:
%Vor%
Damit es funktioniert, müssen wir etwas reference_wrapper
magic machen:
%Vor%
Schließlich kann der Code vereinfacht werden, indem das Äquivalent von std::plus
für den Shift-Operator verwendet wird, in modernem C ++ sollte dies wie folgt aussehen:
%Vor%
Was kann verwendet werden als:
%Vor%
Schließlich können wir definieren:
%Vor%
Was kann als
verwendet werden?
%Vor%
Schließlich gibt es kein Dilemma über den Typ von output_iterator
hier.