Сравнение адреса std::endl
-
22-09-2019 - |
Вопрос
Я проверяю фрагмент существующего кода и обнаружил, что он ведет себя по-другому при компиляции с помощью 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&) );
};
Решение 2
Для информации:
Заявление if ( p_manip == std::endl )
не компилируется исходным компилятором (gcc 3.4.5, компилятором, на котором изначально был разработан код).
Это означает, что тест не был ошибочным, как я сказал в своем вопросе.
Другие советы
Я бы сказал, что первоначальный автор не осознавал, что это совместимые типы, и выполнил преобразование по спецификации (без требования компилятора).