Hallo, ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende. --- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) ) { // output to console if( log_to_console == true ) { cout << (*out); } // output to log file if( log_to_file == true ) { file << (*out); } return *this; } DebugLog& DebugLog::operator<<( const string out ) { // output to console if( log_to_console == true ) { cout << out; } // output to log file if( log_to_file == true ) { file << out; } return *this; } template<typename T> string DebugLog::str( T str ) { stringstream sstr; sstr << str; return sstr.str(); } DebugLog& DebugLog::operator<<( int8_t out ) { return *this << this->str( (int)out ); } DebugLog& DebugLog::operator<<( uint8_t out ) { return *this << this->str( (int)out ); } DebugLog& DebugLog::operator<<( int16_t out ) { return *this << this->str( out ); } DebugLog& DebugLog::operator<<( uint16_t out ) { return *this << this->str( out ); } DebugLog& DebugLog::operator<<( int32_t out ) { return *this << this->str( out ); } DebugLog& DebugLog::operator<<( uint32_t out ) { return *this << this->str( out ); } DebugLog& DebugLog::operator<<( int64_t out ) { return *this << this->str( out ); } DebugLog& DebugLog::operator<<( uint64_t out ) { return *this << this->str( out ); } --- snap --- Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden? Ich würde nämlich gerne folgendes machen: DebugLog debug; debug << setfill(' ') << setw(3) << i << endl; Viele Grüße Bastian
Hallo Bastian, Bastian Schern schrieb am 09.10.2003 13:03:
ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende.
--- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) ) [...]
Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden?
Ich würde nämlich gerne folgendes machen:
DebugLog debug; debug << setfill(' ') << setw(3) << i << endl;
Als erstes gehe ich mal davon aus, daß deine Klasse eine entsprechende Methode besitzt: class DebugLog { public: virtual SetFill(char chAPad); ... Dann implementierst du den Manipulator so: template <class tParamType> class DebugLogManip { public: typedef DebugLog& (*tfnWork)(DebugLog&, tParamType); // Konstruktoren DebugLogManip(tfnWork fnAWork, tParamType xAArg) : mfnWork(fnAWork), mxArg(xAArg) {}; // Operatoren friend DebugLog& operator<<(DebugLog& oALog, DebugLogManip<tParamType>& oAManip) { return (oAManip.mfnWork(oALog, oAManip.mxArg)); } private: tfnWork mfnWork; tParamType mxArg; }; Ich habe gleich eine Template-Implementation gewählt, da du dann für die div. Manipulatoren nur noch eine einfache Funktion anlegen mußt: inline ios& DebugLogManipSetFill(DebugLog& oALog, char chAPad) { oALog.SetFill(chAPad); return (oALog); } Zu guter Letzt brauchst du für jeden Manipulator noch eine globale Funktion mit der entsprechenden Template-Instantiierung: inline DebugLogManip<char> setfill(char chAPad) { return DebugLogManip<char>(DebugLogManipSetFill, chAPad); } Viel Erfolg Raimund P.S. - ich habe den Code aus dem Gedächtnis hingeschrieben, also sind sicherlich auch noch Syntaxfehler enthalten, aber ich denke, daß die Beispiele prinzipiell funktionieren sollten.
Raimund Hölle schrieb:
Hallo Bastian,
Bastian Schern schrieb am 09.10.2003 13:03:
ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende.
--- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) )
[...]
Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden?
Ich würde nämlich gerne folgendes machen:
DebugLog debug; debug << setfill(' ') << setw(3) << i << endl;
Als erstes gehe ich mal davon aus, daß deine Klasse eine entsprechende Methode besitzt:
class DebugLog { public: virtual SetFill(char chAPad); ...
Dann implementierst du den Manipulator so:
template <class tParamType> class DebugLogManip { public: typedef DebugLog& (*tfnWork)(DebugLog&, tParamType);
// Konstruktoren DebugLogManip(tfnWork fnAWork, tParamType xAArg) : mfnWork(fnAWork), mxArg(xAArg) {};
// Operatoren friend DebugLog& operator<<(DebugLog& oALog, DebugLogManip<tParamType>& oAManip) { return (oAManip.mfnWork(oALog, oAManip.mxArg)); }
private: tfnWork mfnWork; tParamType mxArg; };
Ich habe gleich eine Template-Implementation gewählt, da du dann für die div. Manipulatoren nur noch eine einfache Funktion anlegen mußt:
inline ios& DebugLogManipSetFill(DebugLog& oALog, char chAPad) { oALog.SetFill(chAPad); return (oALog); }
Zu guter Letzt brauchst du für jeden Manipulator noch eine globale Funktion mit der entsprechenden Template-Instantiierung:
inline DebugLogManip<char> setfill(char chAPad) { return DebugLogManip<char>(DebugLogManipSetFill, chAPad); }
Viel Erfolg Raimund
P.S. - ich habe den Code aus dem Gedächtnis hingeschrieben, also sind sicherlich auch noch Syntaxfehler enthalten, aber ich denke, daß die Beispiele prinzipiell funktionieren sollten.
Hui, das sieht aber kompliziert aus. Ich hatte gedacht, dass es ähnlich wie mit "endl" funktioniert. Werde es aber gleich mal ausprobieren. Viele Grüße Bastian
Raimund Hölle schrieb:
Hallo Bastian,
Bastian Schern schrieb am 09.10.2003 13:03:
ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende.
--- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) )
[...]
Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden?
Ich würde nämlich gerne folgendes machen:
DebugLog debug; debug << setfill(' ') << setw(3) << i << endl;
[...]
P.S. - ich habe den Code aus dem Gedächtnis hingeschrieben, also sind sicherlich auch noch Syntaxfehler enthalten, aber ich denke, daß die Beispiele prinzipiell funktionieren sollten.
Ich habe das ganze mal wie unten gemacht, es gibt aber ein Paar Fehler, die ich nicht lösen kann. Ich habe die Fehlermeldungen des Compilers hinter oder unter die Codezeile geschrieben. class DebugLog { /* * warning: * `class DebugLog' has virtual functions but non-virtual destructor */ public: DebugLog(); ~DebugLog(); bool init( int level, bool console_log, bool file_log, string log_file ); bool check( int level ); string time( ); template<typename T> string str( T str ); string log( string info ); int log( string info, string text, int level = 9 ); DebugLog& operator<<( ostream& (*out)(ostream&) ); DebugLog& operator<<( const string out ); DebugLog& operator<<( int8_t out ); DebugLog& operator<<( int16_t out ); DebugLog& operator<<( int32_t out ); DebugLog& operator<<( int64_t out ); DebugLog& operator<<( uint8_t out ); DebugLog& operator<<( uint16_t out ); DebugLog& operator<<( uint32_t out ); DebugLog& operator<<( uint64_t out ); DebugLog& operator<<( float out ); DebugLog& operator<<( double out ); DebugLog& operator<<( long double out ); //DebugLog& operator<<( long long double out ); virtual DebugLog& SetFill( char chAPad ); private: int debug_level; bool log_to_console; bool log_to_file; ofstream file; }; template <class tParamType> class DebugLogManip { public: typedef DebugLog& (*tfnWork)(DebugLog&, tParamType); // Konstruktoren DebugLogManip( tfnWork fnAWork, tParamType xAArg ) : mfnWork( fnAWork ), mxArg(xAArg) {}; // Operatoren friend DebugLog& operator<<( DebugLog& oALog, DebugLogManip<tParamType>& oAManip ) { return oAManip.mfnWork( oALog, oAManip.mxArg ); } private: tfnWork mfnWork; tParamType mxArg; }; inline ios& DebugLogManipSetFill( DebugLog& oALog, char chAPad ) { oALog.SetFill( chAPad ); return oALog; // error: could not convert `oALog' to `std::ios&' } inline DebugLogManip<char> setfill( char chAPad ) { return DebugLogManip<char>(DebugLogManipSetFill, chAPad); // error: invalid conversion from `std::ios&(*)(DebugLog&, char)' /* error: initializing argument 1 of ` * DebugLogManip<tParamType>::DebugLogManip(DebugLog&(*)(DebugLog&, * tParamType), tParamType) [with tParamType = char]' */ } Ich hoffe das ist verständlich so. Viele Grüße Bastian
Hallo Bastian, Bastian Schern schrieb am 10.10.2003 17:42:
Raimund Hölle schrieb:
Hallo Bastian,
Bastian Schern schrieb am 09.10.2003 13:03:
ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende.
--- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) ) [...]
Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden?
Ich würde nämlich gerne folgendes machen:
DebugLog debug; debug << setfill(' ') << setw(3) << i << endl; [...]
P.S. - ich habe den Code aus dem Gedächtnis hingeschrieben, also sind sicherlich auch noch Syntaxfehler enthalten, aber ich denke, daß die Beispiele prinzipiell funktionieren sollten.
Ja, das ist das Problem ... siehe unten.
Ich habe das ganze mal wie unten gemacht, es gibt aber ein Paar Fehler, die ich nicht lösen kann. Ich habe die Fehlermeldungen des Compilers hinter oder unter die Codezeile geschrieben.
class DebugLog { /* * warning: * `class DebugLog' has virtual functions but non-virtual destructor */
==> entweder: - Destruktor virtuell machen: virtual ~DebugLog(); - oder SetFill() nicht virtuell: DebugLog& SetFill( char chAPad );
public: DebugLog(); ~DebugLog(); [...] virtual DebugLog& SetFill( char chAPad ); [...]
inline ios& DebugLogManipSetFill( DebugLog& oALog, char chAPad )
Ist natürlich Unfug, muß heißen: inline DebugLog& DebugLogManipSetFill( DebugLog& oALog, char chAPad ) [...] Gruß Raimund
Raimund Hölle schrieb:
Hallo Bastian,
Bastian Schern schrieb am 10.10.2003 17:42:
Raimund Hölle schrieb:
Hallo Bastian,
Bastian Schern schrieb am 09.10.2003 13:03:
ich habe mir eine eigene Klasse geschrieben, die ich für Ausgaben auf den Bildschirm oder/und in ein File verwende.
--- snip --- DebugLog& DebugLog::operator<<( ostream& (*out)(ostream&) )
[...]
Es werden auch "endl", usw. unterstützt. Wie bekomme ich es hin, dass jetzt auch noch Manipulatoren unterstützt werden?
Ich würde nämlich gerne folgendes machen:
DebugLog debug; debug << setfill(' ') << setw(3) << i << endl;
[...]
P.S. - ich habe den Code aus dem Gedächtnis hingeschrieben, also sind sicherlich auch noch Syntaxfehler enthalten, aber ich denke, daß die Beispiele prinzipiell funktionieren sollten.
Ja, das ist das Problem ... siehe unten.
Ich habe das ganze mal wie unten gemacht, es gibt aber ein Paar Fehler, die ich nicht lösen kann. Ich habe die Fehlermeldungen des Compilers hinter oder unter die Codezeile geschrieben.
class DebugLog { /* * warning: * `class DebugLog' has virtual functions but non-virtual destructor */
==> entweder: - Destruktor virtuell machen: virtual ~DebugLog(); - oder SetFill() nicht virtuell: DebugLog& SetFill( char chAPad );
public: DebugLog(); ~DebugLog();
[...]
virtual DebugLog& SetFill( char chAPad );
[...]
inline ios& DebugLogManipSetFill( DebugLog& oALog, char chAPad )
Ist natürlich Unfug, muß heißen: inline DebugLog& DebugLogManipSetFill( DebugLog& oALog, char chAPad )
[...]
Ich habe das jetzt so geändert und es treten jetzt erst an der Stelle
Fehler auf, wo "setfill('x')" benutzt wird auf.
debug << setfill('a') << endl;
// error: no match for `DebugLog& << DebugLogManip<char>' operator
/*
DebugLog.h|40| error: candidates are: DebugLog&
|| DebugLog::operator<<(std::ostream&(*)(std::ostream&))
DebugLog.h|41| error: DebugLog&
|| DebugLog::operator<<(std::basic_string
participants (2)
-
Bastian Schern
-
Raimund Hölle