Beispiel aus einem Buch, das nicht kompiliert werden kann, konvertiert ifstream in bool

8

Ich bin ein Student von C ++. Ich arbeite durch das Buch "Mit frühen C ++ - Objekten beginnen (9. Ausgabe). Beispiel 27 aus Kapitel 6 (über Funktionen) liest Daten aus einer Datei, kompiliert sie aber nicht. Hier ist der vollständige Code:

%Vor%

Und hier sind die begleitenden Daten für die Datendatei Rainfall.dat:

%Vor%

Das Problem liegt bei dieser Zeile in der Funktion "bool readData":

%Vor%

Ich benutze Visual Studio Community 2017. "someFile" erhält eine rote Linie und das Dropdown-Menü zeigt den folgenden Fehler an:

  

es existiert keine passende Konvertierungsfunktion von " std::basic_istream<char, std::char_traits<char>> " nach " bool " existiert

Ich verstehe die Fehlermeldung nicht wirklich, aber es ist mir gelungen, dieses Programm zum Laufen zu bringen:

Eine einfache Besetzung:

%Vor%

Oder dies als Alternative:

%Vor%

Also, meine wirklichen Fragen sind:

  • Sind meine Lösungen in Ordnung oder gibt es einen besseren Weg?
  • Warum wird überhaupt ein Fehler auf das Bildungsmaterial geworfen, dass Sie? Ich würde mir vorstellen, dass es zuerst gründlich getestet werden sollte. Oder ist das? nur Visual Studio (intelliSense) spezifisch, funktioniert aber prima andere Compiler?
Webbmaster1 10.10.2017, 22:47
quelle

4 Antworten

8

Ich würde

überlegen
  • gibt std::ios& zurück, um die kontextabhängige Konvertierung auf bool

    zu verschieben %Vor%

    Das Ergebnis ist, dass Sie es einfach so benutzen können, wie es ist:

    %Vor%

    Die Schnittstelle wird nur mit #include <iosfwd>

    kompiliert
  • Auslösen der kontextabhängigen Konvertierung manuell:

    %Vor%
sehe 10.10.2017, 23:36
quelle
5

Der Stream hat ein Mitglied

%Vor%

was es in einen bool -Wert umwandelbar macht, aber da der Operator explicit ist, funktioniert das nur in einem Kontext, in dem ein bool erfordert.

Sie haben bereits festgestellt, dass dies if-Anweisungen und explizite Umwandlungen beinhaltet. Es enthält keine anderen Arten von Ausdrücken wie Zuordnungen.

Ursprünglich (C ++ 98) war der Operator nicht explicit (weil solche Dinge noch nicht erfunden waren), also hätte das Codebeispiel wahrscheinlich zu der Zeit funktioniert. Scheint so, als ob das Buch in diesem Teil nicht aktualisiert wurde.

    
Bo Persson 10.10.2017 23:00
quelle
3

Das operator bool für Streams wird in der Basisklasse basic_ios auf die folgende Weise deklariert

%Vor%

Es gibt also keine implizite Konvertierung von std::basic_ifstream in den Typ bool .

Diese Lösung

%Vor%

sieht gut aus.

Sie können auch einen Trick mit dem logischen Negationsoperator folgendermaßen verwenden:

%Vor%

weil nach dem C ++ Standard (5.3.1 Unäre Operatoren)

  

9 Der Operand des logischen Negationsoperators! ist kontextabhängig   zu bool konvertiert (Abschnitt 4); sein Wert ist wahr, wenn das konvertiert wurde   Operand ist sonst falsch und falsch. Der Typ des Ergebnisses ist bool.

Obwohl meiner Meinung nach die erste Funktionsimplementierung besser lesbar ist.

    
Vlad from Moscow 10.10.2017 23:19
quelle
2

Ich nehme an, dass sie es erst später im Buch behandeln, aber ich würde das etwas anders angehen. Ich würde beginnen, indem ich eine Struktur definiere, die den Namen und den Niederschlag für eine Stadt zusammenhält:

%Vor%

Dann würde ich eine Überladung von operator>> definieren, um ein Objekt dieses Typs aus einem Stream zu extrahieren:

%Vor%

Dies ist so ziemlich das Standardformular für Stream-Extraktoren - nehmen Sie Bezug auf einen Stream und einen Verweis auf ein Objekt des Typs, der extrahiert wird, und geben Sie den Stream (wiederum durch Referenz) zurück.

Damit können Sie ziemlich sauber lesen:

%Vor%

Wenn Sie sich fragen, wie das funktioniert: Ein Stream-Objekt unterstützt die Konvertierung in Boolean, was true ergibt, wenn das Lesen aus dem Stream erfolgreich war, und false , wenn es fehlschlägt, also liest es vom Stream bis zum Lesen scheitert, dann hört es auf.

Dies ist auch die Form, die von Stream-Iteratoren erwartet wird, sodass Sie sie ebenfalls verwenden können. Um beispielsweise den gesamten Inhalt der Datei in einem Vektor zu lesen, würden Sie Folgendes tun:

%Vor%     
Jerry Coffin 11.10.2017 00:47
quelle