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 unkringelt

    std::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) {}
    

Log in to reply