c++ - example - ¿Cómo funciona QDebug()<< cosas; agregar una nueva línea automáticamente?
qfile read file (4)
Algo como esto hará:
struct debug {
debug() {
}
~debug() {
std::cerr << m_SS.str() << std::endl;
}
public:
// accepts just about anything
template<class T>
debug &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
std::ostringstream m_SS;
};
Lo cual debería permitirle hacer cosas como esta:
debug() << "hello world";
He usado un patrón como este combinado con un bloqueo para proporcionar un sistema de registro como el flujo que puede garantizar que las entradas de registro se escriban atómicamente.
NOTA : código no probado, pero debería funcionar :-)
Estoy tratando de implementar mi propia secuencia de depuración-salida de estilo QDebug (), esto es básicamente lo que tengo hasta ahora:
struct debug
{
#if defined(DEBUG)
template<typename T>
std::ostream& operator<<(T const& a) const
{
std::cout << a;
return std::cout;
}
#else
template<typename T>
debug const& operator<<(T const&) const
{
return *this;
}
/* must handle manipulators (endl) separately:
* manipulators are functions that take a stream& as argument and return a
* stream&
*/
debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
{
// do nothing with the manipulator
return *this;
}
#endif
};
Uso típico:
debug() << "stuff" << "more stuff" << std::endl;
Pero me gustaría no tener que agregar std :: endl;
Mi pregunta es, básicamente, ¿cómo puedo saber cuándo el operador de tipo de devolución << no va a ser utilizado por otro operador << (y así anexar endl)?
La única forma en que puedo pensar para lograr algo como esto sería crear una lista de cosas para imprimir asociadas con cada objeto temporal creado por debug (), luego imprimir todo, junto con la línea nueva final (y podría hacer cosas inteligentes como insertar espacios) en ~ debug (), pero obviamente esto no es ideal ya que no tengo una garantía de que el objeto temporal vaya a ser destruido hasta el final del alcance (¿o no?).
Cuando escribe que este es el uso típico:
debug() << "stuff" << "more stuff" << std::endl;
¿Estás planeando construir un objeto de depuración cada vez que lo usas? Si es así, debería poder obtener el comportamiento que desea haciendo que el destructor de depuración agregue la nueva línea:
~debug()
{
*this << std::endl;
... the rest of your destructor ...
}
Eso significa que no puedes hacer algo como esto:
// this won''t output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
Qt usa un método similar a @Evan. Consulte una versión de qdebug.h para conocer los detalles de la implementación, pero ellos transmiten todo a una secuencia de texto subyacente, y luego descargan la secuencia y una línea final sobre la destrucción del objeto QDebug temporal devuelto por qDebug ().
Se supone que la inserción de flujo ( <<
) y la extracción ( >>
) son no miembros.
Mi pregunta es, básicamente, ¿cómo puedo saber cuándo el operador de tipo de devolución << no va a ser utilizado por otro operador << (y así anexar endl)?
No puedes. Cree una función de miembro para endl
especialmente o anexar un endl
una vez que las llamadas encadenadas hayan finalizado. Documente bien su clase para que los clientes sepan cómo usarla. Esa es tu mejor apuesta.