C++ Logging Class

Started by
15 comments, last by Bregma 12 years, 10 months ago
One slight difficulty is that I would ideally like to make it compatible with std::endl, and I'm unsure how this would be achieved.


This worked for me

template <typename T>
Log& operator<<(T const& value)
{
m_filestream << value;
return *this;
}
Advertisement

[quote name='averron82' timestamp='1309360511' post='4829097']One slight difficulty is that I would ideally like to make it compatible with std::endl, and I'm unsure how this would be achieved.


This worked for me

template <typename T>
Log& operator<<(T const& value)
{
m_filestream << value;
return *this;
}

[/quote]

This does work, but how would you go about implementing std::endl or something equivalent?
std::endl is used to put a new line right? So, why not use "\r\n" instead? That would also give you a new line...
My first 3D game: Click Here
This does work, but how would you go about implementing std::endl or something equivalent?


I never bothered to find out until now :-)

They are called stream manipulators and it's my guess that if you pass the address of a function to a stream then the stream will call that function.

#include <iostream>

std::ostream& hello(std::ostream& os)
{
return os << "world!";
}

int main(int argc, char** argv)
{
std::cout << hello << std::endl;
return 0;
}
Check out this code for an example of how to implement endl and your own stream manipulators with a custom stream wrapper class.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Check out this code for an example of how to implement endl and your own stream manipulators with a custom stream wrapper class.


Nice link, took me a while to realise why I couldn't get endl to work (I'm not using unicode), had to change the wchar_t to plain old char and it works great.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.


This appears to work, however I'm very much open to feedback. One slight difficulty is that I would ideally like to make it compatible with std::endl, and I'm unsure how this would be achieved.

Since you're intent on reinventing std::ostream as closely as possible, here's how std::endl works with std::ostream.

This is a member function of [font="Courier New"]std::ostream[/font].

__ostream_type&
operator<<(__ostream_type& (*__pf)(__ostream_type&))
{
return __pf(*this);
}

It's a member function that takes a function that operates on the ostream and calls it. Now here's [font="Courier New"]std::endl[/font].
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{ return flush(__os.put(__os.widen('\n'))); }

It's a function that operates on an ostream. If you pass the address of [font="Courier New"]std::endl[/font] to [font="Courier New"]std::ostream::operator<<()[/font], it will just call the function. Clever, no?

Using manipulators with parameters is a little trickier: you end up creating a functor that passes the function bound to its parameter (currying). It's not rocket surgery.

I would really recommend just sticking with [font="Courier New"]std::clog[/font] as your logger an replacing its streambuf. You are unlikely to do better and you stand to lose a lot of functionality when you reinvent it yourself.

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement