Comparando o endereço de std :: endl
-
22-09-2019 - |
Pergunta
Estou inspecionando um pedaço de código existente e descobri que ele se comporta de maneira diferente quando compilado com o visual c ++ 9 e o 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;
}
Como o nome sugere, esta é uma classe de log e sobrecarrega operator<<()
Para retirar os finais do fluxo.
Eu descobri por que se comporta de maneira diferente: o teste p_manip == static_cast...
é bem -sucedido com Mingw enquanto falha com o visual c ++ 9.
- Mingw "ignora" o elenco e retorna o endereço real de
std::endl
; - O Visual C ++ 9 realmente lança o ponteiro para o endl e retorna um endereço diferente.
Eu mudei o teste para if ( p_manip == std::endl )
E agora ele se comporta conforme o esperado.
Minha pergunta é: Qual é a lógica por trás de um teste tão complicado (e, de fato, errado)?
Por uma questão de completa:
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&) );
};
Solução 2
Para informação:
A declaração if ( p_manip == std::endl )
Não compila no compilador original (GCC 3.4.5, o compilador no qual o código foi desenvolvido originalmente).
Isso significa que o teste não estava errado, como afirmei em minha pergunta.
Outras dicas
Em um palpite, eu diria que o autor original não percebeu que eram tipos compatíveis e fez a conversão em especificações (sem o compilador que exigia).