std::ostream Verhalten erweitern



  • Hallo zusammen,

    für eine Logger-Klasse muss ich Zeilenumbrüche erkennen. Zuerst wollte ich einen Wrapper um std::ostream schreiben der mir die operator<< Aufrufe abfängt und die zwei Möglichkeiten ( std::endl und \n ) erkennt. Blöderweise komme ich dann an folgenden Punkt:

    bool newline( std::ostream& ( *manip ) (std::ostream&) )
    {
        return (manip == std::endl) ? true : false; // Wrong!
    }
    

    Aber natürlich ist std::endl eine Template-Funktion und keine "Instanz" deren Pointer ich vergleichen könnte. Wahrscheinlich ist das eine völlig falsche Herangehensweise.

    Ich würde also gerne das std::ostream Verhalten erweitern, um Neuzeilen erkennen zu können. Jetzt kenn ich den Aufbau der C++ I/O Library aber nicht so wirklich, und wäre daher für jeden Hinweis dankbar was ich anpassen müsste. Ich denke ich müsste wohl std::streambuf austauschen, bin mir aber nicht sicher.

    Schonmal vielen Dank im Voraus.



  • Eigentlich sollte doch

    return (manip == '\n');
    

    gehen?



  • Öhm nein, manip ist ein Funktionspointer. Den so zu vergleichen macht keinen Sinn.



  • Willst du std::endl vielleicht für deine Logger-Klasse überladen? Also

    namespace std {
      template<> ::logger &endl(::logger &log) {
        // Zeug hier
      }
    }
    


  • Das klingt schonmal recht sinnig 🙂

    Aber std::endl könnte man bei meiner Implementierung immernoch übergeben, da ich keine Manipulatoren ausschließen möchte. Mal zur Erklärung: mein Logger gibt bei einem Write-Aufruf ein Ostream Wrapper Objekt zurück:

    class OstreamWrapper
    {
    public:
        template <typename T>
        OstreamWrapper& operator<<(const T &data)
        { /* ... */ }
    
        OstreamWrapper& operator<<(std::streambuf *buf)
        { /* ... */ }
    
        OstreamWrapper& operator<<(std::ios& ( *manip )(std::ios &))
        { /* ... */ }
    
        OstreamWrapper& operator<<(std::ostream& ( *manip )(std::ostream &))
        { /* ... */ }
    
        OstreamWrapper& operator<<(std::ios_base& ( *manip )(std::ios_base &))
        { /* ... */ }
    };
    

    Damit kann man mit operator<< genauso arbeiten wie mit std::ostream . Der Wrapper schiebt die Daten (oder die Manipulatorfunktion) nur in den "echten" Stream, wenn das Logginglevel passt. Wenn ich jetzt endl für meinen Logger überlade, kann man trotzdem noch std::endl übergeben. Gleiche Problem wie vorher...


Anmelden zum Antworten