|
From: Andrew Falanga on 16 Jan 2008 12:45 Hi everybody, I asked a question yesterday that is related to this one. Below is, basically, what I have in a set of files for a logging class for my programs. Now, I wanted to overload the << operator to be used much like is done with std::cout, etc. Below is code, that won't compile, but that shows what I've done. Basically, when calling my overloaded << function, I need to have certain things done if the argument is either of type logModes or logDirectives. If not, use the template to generate code for it. //Log.h enum logModes { stdoutonly, logfileonly, clear }; enum logDirectives { flush }; #define FLUSH_LOG flush; class Log { std::string logFileName; std::fstream logFile; logModes currMode; public: // c-tors and d-tors here template <typename T> Log& operator << ( T t ) { std::ostringstream os; os = t; logFile << os.str(); return *this; } Log& operator << ( logModes ); Log& operator << ( logDirectives ); }; Now, the definitions for the two overloaded versions of the "<<" function are in Log.cpp. I was beginning to think, however, that although all modules compiled and linked, when I ran my programs the over loaded functions don't get called because the log files were getting zeros instead of new lines for lines like: # include <Log.h> Log myProgLog; myProgLog << "This is a log line" << FLUSH_LOG; Which ended up being, "This is a log line0" in my log files. This lead me to believe that the compiler wasn't selecting which function to use correctly. Andy
From: Ron Natalie on 17 Jan 2008 08:09 You're going about it the wrong way. You'll never get operator<< to work property the way you are trying to do it because class operator<< overloads expect to deal with ostreams. What you want to do is define a stream buffer that outputs to your log file and init an ostream from it. Here's a little hack version of one // Not the most efficient implementation class LogStreamBuf : public std::basic_streambuf<char, std::char_traits<char> > { virtual int_type overflow(int_type ic) { if(ic != EOF) { char c = ic; LogPut(&c, 1); } return ic; } virtual std::streamsize xsputn(const char* s, std::streamsize num) { LogPut(s, num); return num; } } Replace LogPut in xsputn with one that writes to your log file. std::ostream LogOut(&logbuf); LogOut << "this will work with anything that has an ostream<< overload\n";
From: Andrew Falanga on 17 Jan 2008 10:13 On Jan 17, 6:09 am, Ron Natalie <r...(a)spamcop.net> wrote: > You're going about it the wrong way. You'll never > get operator<< to work property the way you are trying > to do it because class operator<< overloads expect to > deal with ostreams. > > What you want to do is define a stream buffer that > outputs to your log file and init an ostream from > it. > > Here's a little hack version of one > > // Not the most efficient implementation > class LogStreamBuf : public std::basic_streambuf<char, > std::char_traits<char> > { > virtual int_type overflow(int_type ic) { > if(ic != EOF) { > char c = ic; > LogPut(&c, 1); > } > return ic; > } > virtual std::streamsize xsputn(const char* s, std::streamsize num) { > LogPut(s, num); > return num; > } > > } > > Replace LogPut in xsputn with one that writes to your log file. > > std::ostream LogOut(&logbuf); > > LogOut << "this will work with anything that has an ostream<< overload\n"; Ron, I must admit to not fully understanding what it is you're doing. Can you walk though it step by step? Andy
|
Pages: 1 Prev: Implementation question on template functions Next: Array error |