<div>magistral amigo mio!!</div>
<div> </div>
<div>es impresionante el lenguaje c++</div>
<div> </div>
<div>gracias por tomarte tanto molestias en darme una respuesta tan detallada</div>
<div>lo entendi todo tan bien como lo has explicados</div>
<div>gracias de nuevo</div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div><br><br> </div>
<div><span class="gmail_quote">El día 26/03/07, <b class="gmail_sendername">Steven Davidson</b> <<a href="mailto:steven@conclase.net">steven@conclase.net</a>> escribió:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">Hola Pedro,<br><br>El pasado 2007-03-26 04:30:08, Pedro Mateo escribió:<br><br>PM> /*<br>PM>     saludo
<br>PM>     he creado una plantilla para poder sobrecargar << de mi clase a<br>PM> cualquier otra<br>PM>     esto funciona para cout pero no para stringstream<br>PM>     en el siguiente codigo me explico mejor
<br>PM> */<br>PM> #include <iostream><br>PM> #include <sstream><br>PM> using namespace std;<br>PM> class miclase{<br>PM>        public:<br>PM>        template <typename T> friend<br>
PM>        T& operator<<(T& o, const miclase& x)     {  return o<<"esta es<br>PM> miclase";}<br>PM> };<br>PM> main(){<br>PM>     miclase x;<br>PM>     cout<<x<<endl;  //esto me sale bien
<br>PM>     //   hasta aqui si no agrega las siguientes lineas el programa se<br>PM> compila sin errores<br>PM>     //   puede comentar las siguientes lineas para verificar lo que digo<br>PM>       stringstream c;
<br>PM>     c<<x;<br>PM>     cout<<c.str()<<endl;<br>PM>         //     el punto es que la plantilla que funciona en cout<<x<<endl;<br>PM>         //     entiendo que deberia funcionarme en c<<x;
<br>PM>         //     me da el siguiente error al compilar<br>PM>         /*<br>PM>                 test.cpp: In function 'T& operator<<(T&, const miclase&)<br>PM> [with T = std::stringstream]':
<br>PM>                 test.cpp:23:   instantiated from here<br>PM>                 test.cpp:12: error: inicialización inválida de la referencia<br>PM> de tipo 'std::stringstream&' desde una expresión de                     tipo
<br>PM> 'std::basic_ostream<char, std::char_traits<char> >'<br>PM>         */<br>PM> }<br><br>El error está en la función. Escribes:<br><br>template <typename T><br>T& operator<<( T& o, const miclase& x )
<br>{<br>return o << "esta es miclase";<br>}<br><br>El problema es que la clase 'stringstream' no tiene sobrecargada ningún operador. En este caso, no existe la siguiente definición:<br><br>stringstream & operator<<( stringstream &, const char * );
<br><br>Pero sí existe la siguiente:<br>ostream & operator<<( ostream &, const char * );<br><br>Como la clase 'stringstream' hereda de 'iostream' y ésta hereda de 'istream' y 'ostream', entonces podemos usar objetos de 'stringstream' en cualesquier funciones y operadores sobrecargados de 'ostream' e 'istream. Esto es,
<br><br>stringstream ss;<br><br>ss << "hola";<br><br>Realmente, acabamos por hacer lo siguiente:<br><br>ostream &os = ss;<br>os << "hola";<br><br>Es decir, terminamos por invocar el operador sobrecargado << de 'ostream'. Esto implica que se retornará una referencia a un objeto de tipo 'ostream', ya que usamos el operador sobrecargado para 'ostream'.
<br><br>Dicho lo anterior, el compilador nos muestra el error, ya que no hay posibilidad de convertir un objeto 'ostream' a 'stringstream'. Volviendo a tu función-plantilla:<br><br>template <typename T>
<br>T& operator<<( T& o, const miclase& x )<br>{<br>return o << "esta es miclase";<br>}<br><br>vemos el error al usar 'stringstream', ya que se generará este operador sobrecargado:
<br><br>stringstream& operator<<( stringstream& o, const miclase& x )<br>{<br>return o << "esta es miclase";<br>}<br><br>Sin embargo, como ya he explicado, usamos el operador << de 'ostream'. Al final, la sobrecarga anterior termina por retornar una referencia a un objeto 'ostream', mientras que tu definición intenta retornar una referencia a un objeto 'stringstream'. O sea, el comportamiento es el siguiente:
<br><br>stringstream& operator<<( stringstream& o, const miclase& x )<br>{<br>ostream &__temp = o;<br>__temp << "esta es miclase"; // ostream &operator<<( ostream &, const char * )
<br>stringstream &__ret = __temp;  // <--- ERROR<br>return __ret;<br>}<br><br>El error está en que no existe la conversión de 'ostream' a 'stringstream'.<br><br>Tenemos dos soluciones que podemos implementar:
<br><br>1. Reescribir la definición de la plantilla para retornar la referencia correcta. Esto es,<br><br>template <typename T><br>T& operator<<( T& o, const miclase& x )<br>{<br>o << "esta es miclase";
<br>return o;<br>}<br><br>2. No usar el parámetro T tan genéricamente. O sea, restrinjamos el tipo T. Sugiero reescribir la definición de la plantilla de esta manera:<br><br>template <typename T><br>basic_ostream<T>& operator<<( basic_ostream<T>& o, const miclase& x )
<br>{<br>return o << "esta es miclase";<br>}<br><br>De esta manera, cualquier objeto (o referencia) de la clase-plantilla 'basic_ostream' puede tomar un objeto de la clase 'miclase'. Esto significa que cualquier objeto de la clase base o sus derivadas pueden hacer uso de este operador. En este caso, el parámetro T de la plantilla hace alusión al tipo de los elementos del canal que típicamente será 'char' o 'wchar_t'.
<br><br>Supongo que también puedes optar por definir ambas plantillas. Por ejemplo,<br><br>template <typename T><br>T& operator<<( T& o, const miclase& x )<br>{<br>// Hacer algo aquí<br>}<br><br>template <typename T>
<br>basic_ostream<T>& operator<<( basic_ostream<T>& o, const miclase& x )<br>{<br>return o << "esta es miclase";<br>}<br><br>En este caso, definimos un operador general 'T' y otro especializado 'basic_ostream<T>'. Con la primera sobrecarga, podemos usar otros tipos de objetos, como por ejemplo,
<br><br>class MiOtraClase {...};<br>...<br>miclase x;<br>MiOtraClase moc;<br><br>moc << x;<br><br><br>Espero haber aclarado la duda.<br><br>Steven<br>_______________________________________________<br>Lista de correo Cconclase 
<a href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br><a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
</a><br>Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br></blockquote></div><br>