Вопрос

Я проверяю фрагмент существующего кода и обнаружил, что он ведет себя по-другому при компиляции с помощью 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, компилятором, на котором изначально был разработан код).

Это означает, что тест не был ошибочным, как я сказал в своем вопросе.

Другие советы

Я бы сказал, что первоначальный автор не осознавал, что это совместимые типы, и выполнил преобразование по спецификации (без требования компилятора).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top