pregunta originalCómo sobrecargar el operador << que no tomar o devolver ostream
Estoy escribí una clase de registro en el que el objetivo es ser capaz de hacer esto:
// thread one
Logger() << "Some string" << std::ios::hex << 45;
// thread two
Logger() << L"Some wide string" << std::endl;
Actualmente mi cabecera Logger es como la siguiente:
#pragma once;
#include <ostream>
class Logger
{
public:
Logger();
~Logger();
std::ostream* out_stream;
};
template <typename T>
Logger& operator<< (Logger& logger, T thing) {
*logger.out_stream << thing;
return logger;
}
Algunas notas acerca de esta clase:
- La compatibilidad multiplataforma no es un problema.
- Dentro de Logger.cpp hay una clase singleton que se encarga de crear el ostream "real".
- El constructor y el deconstructor de Logger realizan el bloqueo necesario del singleton.
que tienen tres problemas:
- ¿Cómo hago que el operador < < función de un amigo o miembro para poder establecer flujo_out como privada?
- ¿Cómo hago que la función del operador < < funcione para manipuladores?
- ¿Cómo puedo agregar una especialización para que si T es un WCHAR * o std :: wstring, lo convierta en char * o std :: string antes de pasarlo a out_stream? (Puedo hacer la conversión La pérdida de caracteres Unicode alta no es un problema en mi caso..)
Resumen de lo aprendido en las respuestas: plantilla
- puesto delante de amigo en lugar de después.
- std :: ios :: hex no es un manipulador. std :: hex es un manipulador.
resultado final
#pragma once
#include <ostream>
#include <string>
std::string ConvertWstringToString(std::wstring wstr);
class Logger
{
public:
Logger();
~Logger();
template <typename T>
Logger& operator<< (T data) {
*out << data;
return *this;
}
Logger& operator<< (std::wstring data) {
return *this << ConvertWstringToString(data);
}
Logger& operator<< (const wchar_t* data) {
std::wstring str(data);
return *this << str;
}
private:
std::ostream* out;
};
Tu resultado es incorrecto. no se permiten especializaciones en el alcance de la clase :) simplemente sobrecargúelos (omita la plantilla <> parte) Se requiere en la respuesta de Adam (que los especializa en el ámbito del espacio de nombres) ya que de lo contrario las (entonces funciones normales del operador) ya no son amigas. –
Curiosamente, funcionó con ellos allí. Pero, para ser correcto, los eliminé de todos modos. ¡Gracias! –