I am developing a logger class that overloads the stream insertion operator.
I am having trouble catching the std::flush
manipulator.
First, a quick summary of what I do:
Given an object of LogClass
, I want to do the following:
LogClass logger;
logger << "Some text" << std::flush;
... and catch the std::flush
manipulator.
All input is sent directly to an internal string stream for later logging by the following inlined operator (which works fine):
class LogClass
{
// ...
std::ostringstream m_internalStream;
template <typename T>
LogClass & operator<<(const T & rhs)
{
m_internalStream << rhs;
return *this;
}
// ...
};
I am trying to catch the std::flush
manipulator by overloading as follows (which also works fine):
LogClass & LogClass::operator<<(std::ostream & (*manip)(std::ostream &))
{
std::ostream & (* const flushFunc)(std::ostream &) = std::flush;
// Is the supplied manipulator the same as std::flush?
if ((manip == flushFunc)) {
flush(); // <-- member function of LogClass
} else {
manip(m_stream);
}
return *this;
}
The problem shows if I try to make the local variable flushFunc
static, as follows:
static std::ostream & (* const flushFunc)(std::ostream &) = std::flush;
In this case, the value of the incoming manip
pointer is not equal to flushFunc
.
Why is that? Does it have anything to do with template instantiations of the std::flush
function for char
?
I am using MS Visual Studio 2010 Pro.
The problem also shows in this small working code snippet:
#include <iostream>
#include <iomanip>
int main(int, char **)
{
static std::ostream & (* const staticFlushPtr)(std::ostream &) = std::flush;
std::ostream & (* const stackFlushPtr)(std::ostream &) = std::flush;
std::cout << std::hex <<
"staticFlushPtr: " << (void *) staticFlushPtr << "\n"
"stackFlushPtr: " << (void *) stackFlushPtr << "\n";
return 0;
}
... which gives this output on my machine:
staticFlushPtr: 013F1078
stackFlushPtr: 0FF10B30
Any ideas?
Best regards, Rein A. Apeland
This looks like a definite bug in the compiler. If there were DLLs or such involved, I could understand it, or at least make excuses, but in such a trivial example as your
main
... (g++ gets it right.)About all I can suggest is that you insert a filtering streambuf in your output, which catches calls to
sync
.