From: Fabian on
Hi Uli,

> BTW: a very convenient feature of C++ IOStreams is the overloaded rdbuf()
> function. Using that, you can easily redirect a stream to stdout, a file or
> any other stream:
>
> int main() {
> std::ofstream out("program.log");
> std::cout.rdbuf(out.rdbuf());
> :

Is it possible to redirect the output to multiple targets, e.g. to both a
file and the console?

Thanks,

Fabian
From: Ulrich Eckhardt on
Fabian wrote:
>> std::ofstream out("program.log");
>> std::cout.rdbuf(out.rdbuf());
>> :
>
> Is it possible to redirect the output to multiple targets, e.g. to both a
> file and the console?

Yes. For that, you need a 'streambuf' that distributes output to two
targets. The 'streambuf' is the part of an IOStream that does the actual IO
and it has several methods that you can override and customise. I believe
that Boost has several helpers to make such things easier than with plain
C++, otherwise you can surely detect a few examples on the net.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932
From: Fabian on
Hi Uli,

> Anyway, back to the issue you actually came for, instead of adding various
> overloads, use templates:

There obviously is a problem: As the template (be it a standalone function
or a static class method) has to be usable from different dlls I have to put
it in a "common" dll. Dll-exporting templates only works with explicit
specialization (in the cpp file). So in this case there's no difference to
writing the overloads. Or have I overseen sth.?

Thx,

Fabian
From: Ulrich Eckhardt on
Fabian wrote:
>> Anyway, back to the issue you actually came for, instead of adding
>> various overloads, use templates:
>
> There obviously is a problem: As the template (be it a standalone function
> or a static class method) has to be usable from different dlls I have to
> put it in a "common" dll. Dll-exporting templates only works with explicit
> specialization (in the cpp file). So in this case there's no difference to
> writing the overloads. Or have I overseen sth.?

Yes, you basically split the code in two parts:
1. Template functions that format the log messages.
2. Non-template functions that write the log message or configure the
logger.

The first category is inline in a header, the second one can be exported
from a DLL.

BTW: in case you are using VC6, now is a time to upgrade. With that
compiler, you further have to split the code in a baseclass that can be
exported from a DLL and a derived class (completely inline) that contains
the templates. Otherwise, you will get linker problems. At least I seem to
remember something like that...

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932
From: Fabian on
Hello Uli,

is there any possibility to define default parameters? Default parameters
for templates are the default types, right? But if I could do sth. like

template void PrintError(const char*, const char* = 0, const char* = 0,
const char* = 0, const char* = 0);

for the specialization in the cpp file, I wouldn't have to write
specializations for a different number of parameters. But the compiler (btw:
I'm quite up to date: Visual Studio 2008) doesn't like it:

'PrintError' : an explicit specialization of a function template cannot have
any default arguments

Thx,

Fabian