I am inspecting a piece of existing code and found out it behaves differently when compiled with Visual C++ 9 and MinGW:
inline LogMsg& LogMsg::operator<<(std::ostream& (*p_manip)(std::ostream&) )
{
if ( p_manip == static_cast< std::ostream& (*)(std::ostream&) > ( &std::endl<char, std::char_traits<char> >) )
{
msg(m_output.str());
m_output.str( "" );
}
else
{
(*p_manip) (m_output); // or // output << p_manip;
}
return *this;
}
As the name suggests, this is a log class and it overloads operator<<()
to strip endls from the stream.
I found out why it behaves differently: the test p_manip == static_cast...
succeeds with MinGW while it fails with Visual C++ 9.
- MinGW "ignores" the cast and returns the real address of
std::endl
; - Visual C++ 9 actually casts the pointer-to-endl and returns a different address.
I changed the test to if ( p_manip == std::endl )
and now it behaves as expected.
My question is: what is the rationale behind such a complicated (and, as a matter of fact, wrong) test?
For the sake of completness:
class LogStream
{
public:
LogStream() {}
protected:
std::ostringstream m_output;
};
class LogMsg : public LogStream
{
friend LogMsg& msg() ;
static LogMsg s_stream;
public:
LogMsg() {}
template <typename T>
inline LogMsg& operator<<(T p_data);
inline LogMsg& operator<<(std::ostream& (*p_manip)(std::ostream&) );
};
At a guess, I'd say the original author didn't realise they were compatible types, and did the conversion on spec (without the compiler requiring him to).
For information:
The statement if ( p_manip == std::endl )
does not compile on the original compiler (gcc 3.4.5, the compiler on which the code was originally developed).
That means the test was not wrong as I stated in my question.
精彩评论