It's hackish, I know, but I recently needed to implement a stream class which would act mostly like a standard stream, but which would detect the std::endl manipulator and special-case it's behaviour. My first attempt at a particular method implementation was...
mystream& mystream::operator<< (std::basic_ostream<char>& (*p) (std::basic_ostream<char>&))
{
if (p == &std::endl)
{
// Handle special case
}
else
{
m_Underlying_Stream << p;
}
return *this;
}
The trouble with this is that the compiler doesn't know which overload of std::endl
I'm referring to. I resolved it as follows...
mystream& mystream::operator<< (std::basic_ostream<char>& (*p) (std::basic_ostream<char>&))
{
typedef std::basic_ostream<char>& (*ENDL_T) (std::basic_ostream<char>&);
const ENDL_T l_ENDL (&std::endl);
if (p == l_ENDL)
{
// Handle special case
}
else
{
m_Underlying_Stream << p;
}
return *this;
}
That is the compiler can resolve the overload in the context of an initialisation (and for assignment too, as another experiment proved), but not for operator==
.
The compiler in question is MinGW GCC 4.4.0, but I don't think this is likely to be a compiler issue.
I had a look around and found this question...
http://stackoverflow.com/questions/705854/c-how-to-get-the-address-of-an-overloaded-member-function
If my code has a const issue, I don't know where the missing const needs to go. I can't see any other obvious type issue.
I have some vague ideas about number-of-steps issues WRT overloading or implicit casting, but nothing concrete. So - can anyone explain clearly what is wrong with my first example, why the second version fixes it, and how I can safely indicate which overload I mean when taking the address of a function.
BTW - I can guess some people won't like me testing directly for the address of std::endl
, and will point out that this is fragile - e.g. someone could have their own manipulator which calls std::endl
which I wouldn't spot. In general this is true, but in this special case, the hack saves a lot of time and the nastiness just doesn't matter.