Re: Problems deriving from std::ostringstream
On May 8, 4:57 pm, Adrian <n...@bluedreamer.com> wrote:
I am having some problems deriving a logging class from
std::stringstream and I dont understand why it is not work.
Main goal of this I am trying to replace 1000's of lines in
some old code that is of the style
Lock();
stream << "some message";
Unlock();
Main questions are:
1. Why does the temporary version not work with class Wibble
(compiler cannot match an operator<< func)
2. Why does the temporary version output address of char *
rather then the string
The short answer is that the standard streams have identity, and
are not designed to be used as temporary objects. What you need
is a wrapper or handle class which contains a pointer to the
stream and overloads all of the operators.
The literal answer is that some of the operator<< functions are
members, others free functions which take a non-const reference
to the stream as the first argument. Since you can't bind a
temporary to a non-const reference, only the first are taken
into consideration in overload resolution, which leads to some
surprises: the overloads for integral and floating point types
are not members, so aren't found (and result in a compiler
error), and the overload for void* is a member, but the one for
char* isn't, so a string literal finds the first (because of the
implicit conversion of any pointer type to void*), rather than
the second.
Note that this problem only affects the first operation; the
return value of all of the << operators is an ostream&, which
will bind to the ostream&. For a single instance, the simplest
solution is to do something like:
StreamType().flush() << ...
(Traditionally, StreamType() << "" was used, but the standards
committee changed the << operator for char const* from a member
to a free function.)
Do I need to add operator<< for all the standard types?
No. You need a class which doesn't derive from an ostream, but
rather contains a reference to one, and defines all of the <<
operators (by means of a simple template) to the stream it
refers to. If the temporary might be copied (usually the case),
you probably need some sort of reference counting to ensure that
the real "disposal" only occurs when the last instance is
destructed, see OutputStreamWrapper in the IO subsystem at
http://kanze.james.neuf.fr/code-en.html.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34