how to pass the function 'endl' as a parameter?

L

Leo jay

dear all,

i want to write log on disk file when macro NEED_DO_LOG is defined.
otherwise, do nothing.
so i wrote code like this:
#ifdef NEED_DO_LOG
fstream fsLogFile (...);
#else
CDummyStream fsLogFile;
#endif // #ifdef ASSAENGINE_NEED_DO_LOG

what i need to do now is making the CDummyStream acts like a fstream.
i wrote these code:
template <typename T>
CDummyStream& operator << (CDummyStream& dummy, const T& t)
{
return dummy;
}
above code can handle int, double, etc. but it can't handle the
function 'endl'.
if i write:
fsLogFile << endl;
the vs.net2003 compiler complains it could not deduce template argument
for 'overloaded function type' from 'overloaded function type'. what's
the meaning of that?

is that possible to pass endl as a parameter?

thanks.
 
L

Leo jay

Lally said:
Considered overloading for char *, and passing in "\n" ?

thanks for your reply.

but the endl function will call the flush funcion automatically to
ensure the data is written into disk file.

if i just pass "\n", the data may not be written into disk file
instantly, if the program crashs i may lost my log, that would be a big
trouble.
 
B

benben

Leo said:
dear all,

i want to write log on disk file when macro NEED_DO_LOG is defined.
otherwise, do nothing.
so i wrote code like this:
#ifdef NEED_DO_LOG
fstream fsLogFile (...);
#else
CDummyStream fsLogFile;
#endif // #ifdef ASSAENGINE_NEED_DO_LOG

what i need to do now is making the CDummyStream acts like a fstream.
i wrote these code:
template <typename T>
CDummyStream& operator << (CDummyStream& dummy, const T& t)
{
return dummy;
}
above code can handle int, double, etc. but it can't handle the
function 'endl'.
if i write:
fsLogFile << endl;
the vs.net2003 compiler complains it could not deduce template argument
for 'overloaded function type' from 'overloaded function type'. what's
the meaning of that?

is that possible to pass endl as a parameter?

Overload the operator<< of course:

CDummyStream& operator<<(const CDummyStream& c,
std::eek:stream& (*fn)(std::eek:stream&))
{
return c;
}
 
L

Leo jay

benben said:
Overload the operator<< of course:

CDummyStream& operator<<(const CDummyStream& c,
std::eek:stream& (*fn)(std::eek:stream&))
{
return c;
}

yes!!, what's what i wanted!

the return type should be const too.

why i can't use template?
is there any significant difference between:
const CDummyStream& operator<<(const CDummyStream& c,
std::eek:stream& (*fn)(std::eek:stream&))
{
return c;
}
and
template<typename T>
const CDummyStream& operator<<(const CDummyStream& c,
T& (*f)(T&))
{
return c;
}
why the second one can't be compiled?
 
T

Tom Widmer

Leo said:
dear all,

i want to write log on disk file when macro NEED_DO_LOG is defined.
otherwise, do nothing.
so i wrote code like this:
#ifdef NEED_DO_LOG
fstream fsLogFile (...);

Shouldn't a log file be an ofstream rather than an fstream?
#else
CDummyStream fsLogFile;
#endif // #ifdef ASSAENGINE_NEED_DO_LOG

what i need to do now is making the CDummyStream acts like a fstream.
i wrote these code:
template <typename T>
CDummyStream& operator << (CDummyStream& dummy, const T& t)
{
return dummy;
}
above code can handle int, double, etc. but it can't handle the
function 'endl'.
if i write:
fsLogFile << endl;
the vs.net2003 compiler complains it could not deduce template argument
for 'overloaded function type' from 'overloaded function type'. what's
the meaning of that?

is that possible to pass endl as a parameter?

You need a few more overloads, to help the compiler with template
argument deduction (remembering that endl is a templated function, so
the compiler doesn't know which specialization to use when all that is
requested is a "T"):

inline CDummyStream& operator << (CDummyStream& dummy, std::ios_base&
(*manip)(std::ios_base&))
{
return dummy;
}
inline CDummyStream& operator << (CDummyStream& dummy,
std::basic_ios<char>& (*manip)(std::basic_ios<char>&))
{
return dummy;
}
inline CDummyStream& operator << (CDummyStream& dummy, std::eek:stream&
(*manip)(std::eek:stream&))
{
return dummy;
}

You should probably also make CDummyStream extend std::eek:stream, if it
doesn't already, and give it a NULL streambuf (e.g. construct the
std::eek:stream base class with std::eek:stream(NULL)), to be on the safe
side. Is threadsafety an issue for you?

Tom
 
B

benben

Leo said:
yes!!, what's what i wanted!

the return type should be const too.

why i can't use template?
is there any significant difference between:
const CDummyStream& operator<<(const CDummyStream& c,
std::eek:stream& (*fn)(std::eek:stream&))
{
return c;
}
and
template<typename T>
const CDummyStream& operator<<(const CDummyStream& c,
T& (*f)(T&))
{
return c;
}
why the second one can't be compiled?

std::endl itself is overloaded. With your template version of operator
<< the compiler can't tell which endl it should pass.

Regards,
Ben
 
A

Alex Vinokur

[snip
is that possible to pass endl as a parameter?
[snip]

--- C++ code ---
#include <iostream>
using namespace std;

void foo (ostream& manip (ostream&))
{
cout << manip << 17 << endl;
}

int main()
{
foo (endl);
return 0;
}
 
M

Michiel.Salters

Leo said:
dear all,

i want to write log on disk file when macro NEED_DO_LOG is defined.
otherwise, do nothing.

Easiest solution is to use a null_streambuf when #ifndef NEED_DO_LOG.

HTH,
Michiel Salters
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top