transmisión transmision toyota recomendable millas funcionamiento cuantas costo cambio cambiar cambia caja cada automatica aceite c++ logging stream

c++ - toyota - transmision manual



¿Cómo usar mi clase de registro como una transmisión estándar de C++? (4)

En la clase Logger, anule el operador <<.

Haga clic aquí para saber cómo implementar el operador <<.

También puede evitar las instrucciones de registro dentro del código usando la programación orientada a aspectos.

Tengo una clase de registrador que funciona, que saca algo de texto en un richtextbox (Win32, C ++). El problema es que siempre termino usándolo así:

stringstream ss; ss << someInt << someString; debugLogger.log(ss.str());

en su lugar, sería mucho más conveniente usarlo como una secuencia como en:

debugLogger << someInt << someString;

¿Hay una mejor manera que reenviar todo a una instancia interna de secuencia de cadenas? Si hiciera esto, ¿cuándo necesitaría enjuagar?


Necesita implementar el operator << apropiadamente para su clase. El patrón general se ve así:

template <typename T> logger& operator <<(logger& log, T const& value) { log.your_stringstream << value; return log; }

Observe que esto trata con referencias (no const ) ya que la operación modifica su registrador. También tenga en cuenta que debe devolver el parámetro de log para que el encadenamiento funcione:

log << 1 << 2 << endl; // is the same as: ((log << 1) << 2) << endl;

Si la operación más interna no devolvió la instancia de log actual, todas las demás operaciones fallarían en tiempo de compilación (firma de método incorrecta) o se tragarían en el tiempo de ejecución.


La sobrecarga del operador de inserción << no es el camino a seguir. Deberá agregar sobrecargas para todas las funciones endl o cualquier otra definida por el usuario.

El camino a seguir es definir tu propio streambuf y vincularlo a una secuencia. Entonces, solo tienes que usar la transmisión.

Aquí hay algunos ejemplos simples:


Como señaló Luc Hermitte, hay un artículo "Iniciando sesión en C ++" que describe un enfoque muy claro para resolver este problema. En pocas palabras, dado que tiene una función como la siguiente:

void LogFunction(const std::string& str) { // write to socket, file, console, e.t.c std::cout << str << std::endl; }

es posible escribir un contenedor para usarlo en std :: cout de la misma manera:

#include <sstream> #include <functional> #define LOG(loggingFuntion) / Log(loggingFuntion).GetStream() class Log { using LogFunctionType = std::function<void(const std::string&)>; public: explicit Log(LogFunctionType logFunction) : m_logFunction(std::move(logFunction)) { } std::ostringstream& GetStream() { return m_stringStream; } ~Log() { m_logFunction(m_stringStream.str()); } private: std::ostringstream m_stringStream; LogFunctionType m_logFunction; }; int main() { LOG(LogFunction) << "some string " << 5 << " smth"; }

( demostración en línea )

Además, hay una solución muy buena proporcionada por Stewart.