Komisches Verhalten von cout in CONST Methode
-
Hallo,
ich teste gerade den folgenden Source aus dem Buch "Beyond the C++ Standard Library".
#include "stdafx.h" #include <algorithm> #include <functional> #include <iostream> #include <utility> #include <vector> using namespace std; class status { std::string m_name; bool m_ok; public: status(const std::string name) : m_name(name), m_ok(true) {} void break_it() {m_ok = false;} bool is_broken() const {return m_ok;} void report() const { std::cout << m_name; std::cout << " is " << (m_ok ? "working normally" : "terribly broken") << '\n'; } }; int main(int argc, char* argv[]) { using namespace std::placeholders; vector<status> statuses; statuses.push_back(status("status 1")); statuses.push_back(status("status 2")); statuses.push_back(status("status 3")); statuses.push_back(status("status 4")); statuses[1].break_it(); statuses[2].break_it(); for (auto it(begin(statuses)); it != end(statuses); ++it) it->report(); for_each(begin(statuses), end(statuses), std::mem_fun_ref(&status::report)); for_each(begin(statuses), end(statuses), std::bind(&status::report, std::placeholders::_1)); std::cin.get(); return 0; }
Dieser Code sollte laut dem Buch und auch meiner Meinung nach funktionieren.
Dies klappt aber nicht, bereits in der IDE (Visual Studio 2010) wird in Zeile 22
der <<-Operator unkringeltstd::cout << m_name;
Beim Compilieren tritt die folgende Fehlermeldung auf
error C2679: Binärer Operator '<<': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'const std::string' akzeptiert (oder keine geeignete Konvertierung möglich)
Das Programm funktioniert wenn die Zeile 22 folgendermassen ändere.
std::cout << m_name.c_str();
Wie kann man sich dieses Verhalten erklären?
-
Versuch mal <string> zu inkludieren.
-
Ist der Code wirklich so in "Beyond the C++ Standard Library" drin? Der hat nämlich zahlreiche Fehler und Unschönheiten:
- #include <string> fehlt. Das ist wohl dein Problem. Der Author verlässt sich da auf nicht garantierte Abhängigkeiten der Headerdateien.
- is_broken sollte !m_ok zurückgeben
- m_ um Member zu kennzeichnen ist nicht mehr in Mode.
- report() sollte keine Memberfunktion sein.
- using namespace std; aber trotzdem std::XYZ? Der soll sich für eines entscheiden. Empfohlen wird auf using namespace std; zu verzichten.
- int argc, const char *argv[] als Parameter von main, werden aber nicht gebraucht.
- statuses -- lol?
- std::mem_fun_ref vom Standard veraltet, wird bald aus der Standardbibliothek entfernt.
- it(begin(statuses)) -- sehr unüblicher Stil.
- for (auto it(begin(statuses)); it != end(statuses); ++it) -- rofl? for (auto& s : statXXXX)
- std::cin.get(); -- IDE richtig einstellen.
- return 0; -- nicht notwendig.
-
Gar nicht gesehen:
const std::string name
als Parameter ist sehr teuer.status(std::string name) : name(std::move(name)), m_ok(true) {}
-
Danke,
der Header <string> fehlte! Mist. In dem Buch werden nur Code-Snippets aufgeführt ohne Header.
Problem gelöst!
Aber!
badcode schrieb:
- is_broken sollte !m_ok zurückgeben
- report() sollte keine Memberfunktion sein.
- int argc, const char *argv[] als Parameter von main, werden aber nicht gebraucht.
- statuses -- lol?
- std::mem_fun_ref vom Standard veraltet, wird bald aus der
steht so im Buch, mache ich auch anders
badcode schrieb:
[*]m_ um Member zu kennzeichnen ist nicht mehr in Mode.
Warum? Ist Firmenstandard.
badcode schrieb:
[*] using namespace std; aber trotzdem std::XYZ? Der soll sich für eines entscheiden. Empfohlen wird auf using namespace std; zu verzichten.
Warum? In Klassen-Definitionen verwende ich std:: weil ich sie in Header-Dateien auslagere, in CPP-Dateien vereinfacht es das Lesen. (Meine Meinung)
badcode schrieb:
[*]it(begin(statuses)) -- sehr unüblicher Stil.
Warum? hier wird ein neues Objekt angelegt.
badcode schrieb:
[*]std::cin.get(); -- IDE richtig einstellen.
Wie?
badcode schrieb:
[*]return 0; -- nicht notwendig.
[/quote]
Seid wann?Mehr Fragen, als Antworten...
-
Auch klar, falsch abgetippt....
badcode schrieb:
Gar nicht gesehen:
const std::string name
als Parameter ist sehr teuer.status(std::string name) : name(std::move(name)), m_ok(true) {}