2011-05-13 19 views
10

Decir que tengo una clase A y un operador < < declarado así:Cómo sobrecargar el operador ostream << para que funcione con log4cxx en C++?

// A.h 
class A 
{ 
    // A stuff 
}; 
std::ostream& operator<<(std::ostream& os, const A& a); 

en otro lugar que uso mi registrador con A:

LoggerPtr logger(LogManager::getLogger("ThisObject")); 
A a; 
LOG4CXX_INFO(logger, "A: " << a); 

El compilador se queja: binaria '< < ': no ​​se ha encontrado ningún operador que tome un operando de la mano derecha del tipo' const A '(o no hay una conversión aceptable) D: \ dev \ cpp \ lib \ apache-log4cxx \ log4cxx \ include \ log4cxx \ helpers \ messagebuffer.h 190

Este error me lleva a la declaración de la operator<<:

// messagebuffer.h 
template<class V> 
std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) { 
    return ((std::basic_ostream<char>&) os) << val; 
} 

LOG4XX_INFO macro se expande a:

#define LOG4CXX_INFO(logger, message) { \ 
    if (logger->isInfoEnabled()) {\ 
     ::log4cxx::helpers::MessageBuffer oss_; \ 
     logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} 

MessageBuffer "define" operador así:

// messagebuffer.h 
template<class V> 
std::ostream& operator<<(MessageBuffer& os, const V& val) { 
    return ((std::ostream&) os) << val; 
} 

I no entiendo cómo sobrecargar este operador de la manera correcta para hacerlo funcionar. ¿Alguna idea?

+0

¿Qué compilador? –

+0

@ Alan Stokes: Estoy usando Visual Studio 2010 –

+0

Trate de incluir A.h antes messagebuffer.h –

Respuesta

7

usted podría intentar declarar su operador < < en namespace std (que es legal, ya que estás pasando una instancia de su tipo definido por el usuario):

namespace std { 
    ostream& operator<<(ostream& os, const A& a); 
} 
+0

No estoy acostumbrado a contaminar un espacio de nombres que no es mío, pero debo admitir que funcionó como un amuleto. Aclamaciones. –

+0

Me interesa saber por qué el compilador no puede encontrar mi operador en este contexto. –

+0

¡Así que soy yo! Creo que ADL (búsqueda dependiente del argumento) debería hacer que tu código simplemente funcione; pero ADL está lleno de sutilezas, y Visual Studio agrega sus propias idiosincrasias. El truco estándar del espacio de nombres me ha funcionado antes. No es tan malo como parece, una vez que te acostumbras. –

0

No tengo un compilador disponible en este momento, pero creo que el problema se debe a intentar usar el operador de inserción en una cadena constante. "A: " << a

+1

No estoy insertando en una cadena constante; debe haber leído mal la expansión 'LOG4CXX_INFO'. –

2

sugerencia de poner de Alan la definida por el usuario operador en el espacio de nombres std funciona. Pero prefiero poner el operador definido por el usuario en el espacio de nombres log4cxx::helpers, que también funciona. Específicamente,

namespace log4cxx { namespace helpers { 
    ostream& operator<<(ostream& os, const A& a); 
} } 
Cuestiones relacionadas