overloading the insertion operator to take in 'endl'

Started by
6 comments, last by IFooBar 20 years, 7 months ago
here''s the situation. I have a logger class that has a templated insertion operator overload. The logger logs stuff in html. So i need to make a specialization to take in endl and instead of passing in ''\n'' I have to pass in "
" (for html end line). I want to be able to do this logger<< "blah"<< std::endl; here''s a little code to show how the logger class is structured

class logger
{
   std::ofstream mFile;

public:

   template<class T0> logger& operator << ( T0 val )
   {
      mFile<< val;
   }
};
Now I tried making a template specialization that takes in a function pointer that''s in the form of a manipulator

typedef std::basic_ostream<TCHAR, std::char_traits<TCHAR> >& (*_manip)(std::basic_ostream<TCHAR, std::char_traits<TCHAR> >&);
but still dont work. Any help would be greatly appreciated
[size=2]aliak.net
Advertisement
i also have a html logger, but it works a bit diffrent.

i have a base object:
class AInfoString{  public:       friend  std::ostream& operator<< (std::ostream&, axpAInfoString&);       virtual void Log() = 0;       virtual std::string InfoString() = 0;};// note the namespace!!!std::ostream& axp::operator<< (std::ostream& lStream, AInfoString& lRight){  lStream << lRight.InfoString();}


as u can see, log and infostring are pure virtual, and any object that derives from ainfostring must implement them, and when they do, i can use it''s << operator, which calls infostring(). so anything u want to log, just build a string in infostring and that''s it...

cout << CAnyObjectWhichDerivedFromAInfoString;

simple...

Abnormal behavior of abnormal brain makes me normal...
Overload operator << again only have it take a pointer to a function with a return type std::ostream& and that takes a reference or pointer to an ostream as a parameter. Then call that function passing your mFile as a parameter. std::endl is a function. Also, return *this in that function as well as the one you already defined.

IE

class logger{  std::ofstream mFile;public:  template<class T0>    logger& operator << ( T0 val )  {    mFile<< val;    return *this;  }  logger& operator << ( std::ostream& (&Modifier)( std::ostream& ) )  {    Modifier( mFile );    return *this;  }};


EDIT: Fixed/Typos

[edited by - Polymorphic OOP on September 2, 2003 2:50:28 PM]
polymorphic: Your function parameter is exactly the same as my typedef except that I was using a TCHAR instead of a char. It also dosnt work. The compiler gives an error:

error C2678: binary ''<<'' : no operator found which takes a left-hand operand of type ''Rex::Logger'' (or there is no acceptable conversion)


endl is a templated funtion. So wont I need something like a friend specialization in my logger class? something like:

class logger
{
...
template<> friend std::ostream& endl( logger& l )
{
return l.mFile;
}
...
};


although the above dosnt work either
[size=2]aliak.net
I think you''re suppose to watch for the ''\n'' character in your stream-buffer, and then you need to override the flush method of the stream class.

In theory what you need to do is write a new stream buffer, not a new stream class.


Streams aren''t exactly my strong point (nor anyone I know for that matter), so I could be off.

(Just today I got pissed at fstream, and made my own C stdio wrapper, apparently ios::app/ate doesn''t work with binary IO).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Polymorphic's way is the one to use
Of course you might want to make the return type and the argument type of the function pointer something different :
struct logger{  logger & operator <<( logger & (* arg)( logger & ) )  {    return arg( * this );  }};// endl examplelogger & endl( logger & log ){  log << "<br />";  log.flush();  return log;}


Edit: make '\n' a <br />

[edited by - mputters on September 3, 2003 3:56:18 AM]
quote:Original post by IFooBar
polymorphic: Your function parameter is exactly the same as my typedef except that I was using a TCHAR instead of a char. It also dosnt work. The compiler gives an error:


If you're getting an error then your compiler isnt compliant. Make sure you copied it correctly.

quote:Original post by mputters
Of course you might want to make the return type and the argument type of the function pointer something different

But then you have to redefine endl and any other similar functions.

[edited by - Polymorphic OOP on September 3, 2003 4:19:45 AM]
mputters: yeah your way works.

quote:If you''re getting an error then your compiler isnt compliant. Make sure you copied it correctly.


The error has nothing to do with the function pointer decelration or compiler compliance. It happens when I pass endl to the logger. Your function pointer definition was fine. Like I said, same as the one I showed in my first post. The problem is that endl expects a stream object which the logger is not, that''s why it was giving the error.

though the problem with mputters way is

quote:But then you have to redefine endl and any other similar functions.


But I guess that''s ok becuase I only really need to redefine endl and endp. So not a big problem. Cant seem to get it to work the "proper" way. It''s not like Ill be using std::endl/endp anyway.

thanks guys.
[size=2]aliak.net

This topic is closed to new replies.

Advertisement