既存のコードの一部を調べたところ、Visual C++9と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;
}
名前が示すように、これはログクラスでありoperator<<()
、ストリームからendlsを削除するためにオーバーロードします。
動作が異なる理由を見つけました。テストp_manip == static_cast...
はMinGWで成功しますが、Visual C++9では失敗します。
- MinGWはキャストを「無視」し、
std::endl
;の実際のアドレスを返します。 - Visual C ++ 9は、実際にはポインタをendlにキャストし、別のアドレスを返します。
テストをに変更しましたif ( p_manip == std::endl )
が、期待どおりに動作するようになりました。
私の質問は:そのような複雑な(そして実際には間違った)テストの背後にある理論的根拠は何ですか?
完全を期すために:
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&) );
};