2010-02-22 5 views
21

Ich habe Tonnen von operator<<(std::ostream &, const T &) Funktionen geschrieben - sie sind unglaublich nützlich.Verwendet jemand tatsächlich Stream-Extraktionsoperatoren?

Ich habe noch nie eine operator>>(std::istream &, T &) Funktion in echtem Code geschrieben oder sogar die Extraktionsoperatoren für eingebaute Typen verwendet (OK, vielleicht für std::string). Sind diese nur für kurze Beispielprogramme und Lehrbücher geeignet? Ist operator>> eine fehlgeschlagene Funktion von C++?

Fragen wurden über safely overloading stream operators gestellt. Was ich mich wundere ist, wenn jemand das in der Praxis tut.

Auch für etwas einfaches wie reading input from a file in C++ kann ich nicht vorschlagen, operator>> zu verwenden. Es ist zu schwierig, Code zu schreiben, der robust in der Erkennung und Handhabung von Eingabefehlern ist (oder ich weiß nicht wie).

Wenn Sie nicht zustimmen, zeigen Sie bitte ein gutes Beispiel für die Verwendung operator>> - vielleicht durch Beantworten der letzten Frage, die ich verknüpft habe.


Zusammenfassung: Danke für die Antworten jeder, viele gute Meinungen. Manuel's Antwort ließ mich meinen Widerwillen, op>> zu verwenden, überdenken, also akzeptierte ich diesen.

+0

Sie müssen 'op >>' definieren, wenn 'lexical_cast' unterstützt werden soll. (http://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm). – kennytm

Antwort

8

Ich denke, Stream-Extraktor-Operatoren können sehr nützlich sein, wenn sie mit STL-Algorithmen wie std::copy und mit der std::istream_iterator Klasse kombiniert werden.

Lesen Sie this answer, um zu sehen, wovon ich spreche.

+0

Ich mag diese Technik. Ich werde es irgendwann versuchen müssen. – Dan

3

Werte werden häufiger gedruckt als gelesen, daher wird operator<< häufiger verwendet als operator>>. Wenn Sie jedoch Werte lesen möchten, ist operator>> nützlich.

Dass Sie auf Fehler überprüfen müssen, ist nicht spezifisch für operator>>, offensichtlich muss auch jede andere Art, Werte zu lesen, ungültige Eingaben in irgendeiner Weise erkennen.

0

Ich habe den Operator < < stark verwendet, um Listen von Sortieranweisungen, Feldern in Datenbankansichten usw. in meiner Datenbank-API OOFILE zusammenzustellen.

Aus irgendeinem Grund fand eine große Anzahl von Benutzern es intuitiv, den Operator >> zu append a sort field which was a reverse sort zu verwenden. Ich weiß nicht, wer es überhaupt vorgeschlagen hat, aber es hat genug Leute angesprochen, dass es in der API angekommen ist.

zB:

dbSorter arcSort; // declare a sorter 
arcSort << reverse(Date) << FileName; // "normal" way to specify two sort fields 
arcSort >> Date << FileName; // shorthand way that evolved to specify 

Wir auch herkömmliche Verwendung von Operator >> gemacht eine ganze dbTable aus einem Stream zu analysieren.

+0

OK, aber das ist kein istream-Extraktor. Ich habe op >> zum Schreiben Marshalling-Code verwendet, wo ich die vollständige Kontrolle über die Eingabe/Ausgabe hatte und jeder Fehler war fatal. Aber ich habe es nie für die Textverarbeitung nützlich gefunden. – Dan

+0

Ich habe mich gerade selbst korrigiert - OOFILE verwendet das konventionelle Operatormuster >> ruft eine virtuelle Einfügemethode für Tabellen und Felder auf. –

1

Operator >> ist im Wesentlichen Deserialisierung. In meiner begrenzten und anekdotischen Erfahrung ist die meiste Serialisierung/Deserialisierung in C++ auf einer niedrigeren Ebene implementiert als die Stream-Bibliothek. Es muss nicht auf einer niedrigeren Ebene implementiert werden - es ist normalerweise so.

Die Implementierung der benutzerdefinierten Deserialisierung ist nicht immer ein triviales Problem, aber Sie stoßen wahrscheinlich auf die gleichen Probleme, auch wenn Sie sie nicht mit der Stream-Extraktionssyntax implementieren.

Hier ist eine cheezy Verwendung des Stroms Eingabe-Operators, der zumindest geringfügig nützlich ist: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

In diesem begrenzten Umfang, wie es scheint, die korrekte Verwendung ist ziemlich einfach.

+0

Das ist ein interessantes Beispiel, weil es eine "Zeichenfolge" in einen "istringstream" steckt. Die Konsequenz ist, dass bei einem Parse-Fehler die ursprüngliche Eingabe dem Benutzer angezeigt werden kann. Vs. Wenn der Code direkt von einem 'istream' gelesen wurde, ist es zu dem Zeitpunkt, zu dem der Fehler aufgetreten ist, zu spät, um die fehlerhafte Eingabe anzuzeigen. – Dan

+0

Datei- und Netzwerkstreams sind ebenfalls nützliche Beispiele. Die Implementierung jeder Art von Deserialisierung auf Byte-Stream-Ebene wird unordentlich sein, es sei denn, Ihre Bedürfnisse sind sehr einfach. Für größere Anforderungen sollten Sie ein Protokoll entwerfen und das dann implementieren. Eine spezifische Fehlerbehandlung (und möglicherweise eine Fehlerkorrektur und/oder Datenredundanz) kann entworfen werden, in welchem ​​Fall der Code dann offensichtlich wird. –

6

Ja ich verwende den Operator >> (obwohl nicht so häufig wie der Operator < <).Es ist sehr nützlich, um benutzerdefinierte Typen in ihre jeweiligen Objekte zu analysieren und somit die Analyse und die notwendige Fehlerverarbeitung zu zentralisieren. Es ist auch sehr nützlich für die Analyse der Zeichenfolgendarstellung eines Aufzählungstyps.

Betrachten Sie zum Beispiel einen Aufzählungstyp, der eine Frucht darstellt. Sie können den Operator >> verwenden, um eine Zeichenfolge (wie "Apfel", "Banane" usw.) zu analysieren, um den richtigen Enumerationswert zu erhalten.

std::istream &operator>>(std::istream &is, Fruit &fruit) 
{ 
    std::string str; 
    is >> str; 
    if (str == "apple") 
     fruit = APPLE; 
    else if (str == "banana") 
     fruit = BANANA; 
    // other fruits 
    else 
     is.setstate(std::ios::failbit); 
    return is; 
} 

Beachten Sie auch die Verwendung der setstate Methode auf dem istream den Fehlerzustand des Stroms einzustellen, wenn eine unbekannte Zeichenfolge auftritt. Wenn Sie diesen Operator verwenden, können Sie die FailState des Stroms wie folgt überprüfen:

Fruit fruit; 
std::cin >> fruit; 
if (std::cin.fail()) 
    std::cout << "Error: Unknown Fruit!" << std::endl; 
2

ich sie nie schreiben, und ganz selten die „eingebaute“ diejenigen verwenden. Die Extraktionsoperatoren sind ziemlich nutzlos, um interaktive Benutzereingaben zu lesen, da es für einen Stream zu einfach ist, schlecht zu werden. Das Schreiben einer benutzerdefinierten Parsing-Routine ist fast immer einfacher und robuster. Und wenn es um die Serialisierung geht, wenn ich etwas als Text speichern möchte, mache ich es nach einem Industriestandardformat wie XML, für das die Extraktionsoperatoren zum Lesen schlecht geeignet sind. Ansonsten speichere ich die Daten in einer Datenbank oder in einer Binärdatei, die wiederum für den Einsatz mit Extraktoren ungeeignet sind.

2

operator>> ist hilfreich bei der Umwandlung von Zahlen in Textform in eine interne Darstellung.

Es kann auch beim Laden von Daten für Objekte nützlich sein. Im Gegensatz zu scanf, die für verschiedene Typen nicht überladen werden können, können Objekte operator>> überladen. Dadurch wird mehr Daten zum Laden von Objekten bereitgestellt, die interne Darstellung muss nicht bekannt sein, um Daten in das Objekt einzulesen.

Verwandte Themen