unarios sobrecarga relacionales operadores operador matrices c++ stl operator-overloading

c++ - relacionales - sobrecarga de operadores unarios



std:: endl es de tipo desconocido al sobrecargar al operador<< (6)

Sobrecargué al operador <<

template <Typename T> UIStream& operator<<(const T); UIStream my_stream; my_stream << 10 << " heads";

Funciona pero

my_stream << endl;

Da error de compilación:

error C2678: binario ''<<'': no ​​se ha encontrado ningún operador que tome un operando de la izquierda del tipo ''UIStream'' (o no hay una conversión aceptable)

¿Cuál es el trabajo para hacer que my_stream << endl funcione?


Además de la respuesta aceptada, con C ++ 11 es posible sobrecargar el operator<< para el tipo:

decltype(std::endl<char, std::char_traits<char>>)


El problema es que std::endl es una plantilla de función, como su operador << es. Entonces cuando escribes:

my_stream << endl;

le gustará que el compilador deduzca los parámetros de plantilla para el operador así como para endl . Esto no es posible

Por lo tanto, debe escribir sobrecargas adicionales de plantilla << para trabajar con manipuladores. Su prototipo se verá así:

UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));

(hay otros dos, reemplazando std::ostream por std::basic_ios<char> y std::ios_base , que también debe proporcionar si desea permitir todos los manipuladores) y su implementación será muy similar a la de tus plantillas De hecho, es tan similar que puede usar su plantilla para la implementación de esta manera:

typedef std::ostream& (*ostream_manipulator)(std::ostream&); UIStream& operator<<(UIStream& os, ostream_manipulator pf) { return operator<< <ostream_manipulator> (os, pf); }

Una nota final, a menudo escribir un streambuf personalizado, es a menudo una mejor manera de lograr lo que uno trata de lograr aplicando a la técnica que está utilizando.


Hice esto para resolver mi problema, aquí está parte de mi código:

template<typename T> CFileLogger &operator <<(const T value) { (*this).logFile << value; return *this; } CFileLogger &operator <<(std::ostream& (*os)(std::ostream&)) { (*this).logFile << os; return *this; }

Main.cpp

int main(){ CFileLogger log(); log << "[WARNINGS] " << 10 << std::endl; log << "[ERRORS] " << 2 << std::endl; ... }

Obtuve la referencia aquí http://www.cplusplus.com/forum/general/49590/

Espero que esto pueda ayudar a alguién.


Los flujos std no están diseñados para ser subclasificados ya que no tienen métodos virtuales, así que no creo que llegues demasiado lejos con eso. Sin embargo, puedes intentar agregar un std :: ostream para hacer el trabajo.

Para hacer que endl funcione, es necesario implementar una versión del operator<< que tome un puntero a función, ya que así es como se manejan los manipuladores como endl es decir,

UStream& operator<<( UStream&, UStream& (*f)( UStream& ) );

o

UStream& UStream::operator<<( UStream& (*f)( UStream& ) );

Ahora std::endl es una función que toma y devuelve una referencia a std :: basic_ostream para que no funcione directamente con la transmisión, por lo que deberá crear su propia versión que llame a la versión std::endl en su agregado std::iostream .

Editar: Parece que la respuesta de GMan es mejor. Él se vuelve std::endl también!


Vea here para mejores formas de extender IOStreams. (Un poco desactualizado, y adaptado para VC 6, por lo que tendrá que tomarlo con un grano de sal)

El punto es que para que los funtores funcionen (y endl, que tanto salidas "/ n" como rubores es un funtor), necesitas implementar la interfaz completa de ostream.


std::endl es una función y std::cout utiliza implementando el operator<< para tomar un puntero de función con la misma firma que std::endl .

Allí, llama a la función y reenvía el valor de retorno.

Aquí hay un ejemplo de código:

#include <iostream> struct MyStream { template <typename T> MyStream& operator<<(const T& x) { std::cout << x; return *this; } // function that takes a custom stream, and returns it typedef MyStream& (*MyStreamManipulator)(MyStream&); // take in a function with the custom signature MyStream& operator<<(MyStreamManipulator manip) { // call the function, and return it''s value return manip(*this); } // define the custom endl for this stream. // note how it matches the `MyStreamManipulator` // function signature static MyStream& endl(MyStream& stream) { // print a new line std::cout << std::endl; // do other stuff with the stream // std::cout, for example, will flush the stream stream << "Called MyStream::endl!" << std::endl; return stream; } // this is the type of std::cout typedef std::basic_ostream<char, std::char_traits<char> > CoutType; // this is the function signature of std::endl typedef CoutType& (*StandardEndLine)(CoutType&); // define an operator<< to take in std::endl MyStream& operator<<(StandardEndLine manip) { // call the function, but we cannot return it''s value manip(std::cout); return *this; } }; int main(void) { MyStream stream; stream << 10 << " faces."; stream << MyStream::endl; stream << std::endl; return 0; }

Espero que esto te dé una mejor idea de cómo funcionan estas cosas.