elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Sobre carga de operador [Visual Studio 2010]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Sobre carga de operador [Visual Studio 2010]  (Leído 5,005 veces)
Namida

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Sobre carga de operador [Visual Studio 2010]
« en: 15 Diciembre 2010, 21:33 pm »

¡Hola a todos! Tengo el siguiente problema. No se como sobrecargar un operador dentro de una plantilla. Lo he intentando de la siguiente forma y me tira error.

Código:
template<TYPE>class A{
[...] /*Resto del código*/
friend std::ostream &operator << (std::ostream &os,A<TYPE> X);
};

template<TYPE> std::ostream &operator <<(std::ostream &os,A<TYPE> X){
[...] /*Resto del código*/
return os;
};

Gracias de antemano por su ayuda ;)


En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #1 en: 15 Diciembre 2010, 23:12 pm »

Y cual es el error? igual viendo el código lo mas probable es que no se encuentre la definición de la sobrecarga pero preferiría que lo confirmes así partimos del error.

Podes probar dos cosas, una es esta:

Código
  1. template<TYPE>class A{
  2. friend std::ostream &operator << (std::ostream &os,A<TYPE> X){}
  3. };
  4.  

para "obligar" al compilador a ubicar la implementación.

La segunda, tal vez no la mejor pero si la mas sencilla, declarar y definir la sobrecarga en el mismo bloque:

Código
  1. template<TYPE>class A{
  2. friend std::ostream &operator << (std::ostream &os,A<TYPE> X)
  3. {
  4. //etc
  5. return os;
  6. }
  7. };
  8.  

Cualquier cosa ya sabes.

Saludos.


En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Namida

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #2 en: 16 Diciembre 2010, 00:26 am »

Muchas gracias por tu respuestas. Sí, el error es de definición. Implementando directamente la sobrecarga del operador dentro de la clase si me funciona (el segundo ejemplo que mencionas). He intentado separar la declaración de la sobrecarga de su implementación sin éxito.

De todas formas el error dado por el compilador es el siguiente:
Citar
1>------ Operación Generar iniciada: proyecto: Librerias, configuración: Debug Win32 ------
1>  main.cpp
1>main.obj : error LNK2019: símbolo externo "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class matrix<int>)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$matrix@H@@@Z) sin resolver al que se hace referencia en la función _main
1>C:\Documents and Settings\mis documentos\visual studio 2010\Projects\ProyectoDePruebas\Debug\Librerias.exe : fatal error LNK1120: 1 externos sin resolver
========== Generar: 0 correctos, 1 incorrectos, 0 actualizados, 0 omitidos ==========

Sin más, gracias por la ayuda ;)
En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #3 en: 16 Diciembre 2010, 02:15 am »

Postea como has hecho el intento de separar la implementación y lo vemos. Si puedes postea una minima expresion compilable (no importa si tiene ese error) asi lo vemos mas en detalle. El primer ejemplo también tendría que funcionar, y si no funciona eso, con una forward declaration también debería funcionar.

Postea cuando puedas así lo vemos en detalle.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Namida

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #4 en: 16 Diciembre 2010, 07:56 am »

Código:
//Definición de la clase
template<typename TYPE>class matriz{
protected:
unsigned filas,columnas;
TYPE** datos;
public:
matriz (unsigned FILAS,unsigned COLUMNAS);
friend std::ostream &operator << (std::ostream &os,matriz<TYPE> X);
};

//Definición del constructor
template<typename TYPE> matriz<TYPE>::matriz(unsigned FILAS, unsigned COLUMNAS){
filas=FILAS;
columnas=COLUMNAS;
datos=new TYPE *[filas];
for(unsigned i=0;i<filas;i++){
datos[i]=new TYPE [columnas];
for(unsigned j=0;j<columnas;j++){
datos[i][j]=0;
};
};
};

//Sobrecarga del operador
template<typename TYPE> std::ostream &operator << (std::ostream &os, matriz<TYPE> X){
for(unsigned i=0;i<X.filas;i++){
for(unsigned j=0;j<X.columnas;j++){
os<<X.datos[i][j]<<'\t';
};
os<<'\n';
};
return os;
};


int main(int argc,char* argv[]){
matriz<int> A=matriz<int>(4,4);
std::cout<<A<<std::endl;
std::system("pause");
return 0;
};

Ahí te dejo el código básico de lo que, en principio, estoy intentando ejecutar. A ver si le puedes encontrar el fallo por el que no va. Sin más, gracias por todo :D
En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #5 en: 16 Diciembre 2010, 21:11 pm »

Bueno usualmente no me gusta extenderme demasiado en las explicaciones al menos que sea realmente necesario, y en este caso lo es. Viendo el código ya el problema ha quedado claro, espero que la explicación también.  ;D


Cuando el compilador recorre la clase y la analiza, al encontrarse con la declaración friend de la sobrecarga del operador, en este punto:


Código
  1. template<typename TYPE>class matriz{
  2. protected:
  3. unsigned filas,columnas;
  4. TYPE** datos;
  5. public:
  6. matriz (unsigned FILAS,unsigned COLUMNAS);
  7. friend std::ostream &operator << (std::ostream &os,matriz<TYPE> X); // sobrecarga friend
  8. };

el compilador no sabe que dichas funciones en si mismas son templates, entonces asume que la definición de dichas funciones son precisamente, no-template.
Al utilizar los métodos propiamente dichos, el compilador genera una llamada a las versiones no-template de dichos métodos, lo cual seria así:

Código
  1. std::ostream &operator << (std::ostream &os,matriz<TYPE> X);// Sobrecarga friend no-template

pero esos métodos nunca están definidos puesto que en realidad técnicamente no existen. Entonces en ese momento el linker te da el error de referencia indefinida.

La forma de solucionarlo es basicamente aclarándole al compilador que la versión de la función que tiene que buscar es precisamente, un template.

Primero que nada, usamos forward declarations de la clase y de la sobrecarga:

Código
  1. template<typename TYPE> class matriz;
  2. template<typename TYPE> std::ostream &operator <<(std::ostream &os,matriz<TYPE> X);

y luego de eso, agregamos <> a la sobrecarga del operador para que el compilador al recorrer la clase sepa que nos estamos refiriendo a un template:

Código
  1. friend std::ostream &operator << <> (std::ostream &os,matriz<TYPE> X);

y luego lo defines:

Código
  1. template<typename TYPE> std::ostream &operator << (std::ostream &os, matriz<TYPE> X)
  2. {
  3. //la logica aqui
  4. }
  5.  

El código final te debería quedar así:

Código
  1. template<typename TYPE> class matriz; //Forward declaration de la clase
  2. template<typename TYPE> std::ostream &operator <<(std::ostream &os,matriz<TYPE> X); // Forward declaration de la sobrecarga
  3.  
  4. //Definición de la clase
  5. template<typename TYPE>class matriz{
  6. protected:
  7. unsigned filas,columnas;
  8. TYPE** datos;
  9. public:
  10. matriz (unsigned FILAS,unsigned COLUMNAS);
  11. friend std::ostream &operator << <> (std::ostream &os,matriz<TYPE> X); //Especificar versión template
  12. };
  13.  
  14. //Definición del constructor
  15. template<typename TYPE> matriz<TYPE>::matriz(unsigned FILAS, unsigned COLUMNAS){
  16. filas=FILAS;
  17. columnas=COLUMNAS;
  18. datos=new TYPE *[filas];
  19. for(unsigned i=0;i<filas;i++){
  20. datos[i]=new TYPE [columnas];
  21. for(unsigned j=0;j<columnas;j++){
  22. datos[i][j]=0;
  23. };
  24. };
  25. };
  26.  
  27. //Sobrecarga del operador
  28. template<typename TYPE> std::ostream &operator << (std::ostream &os, matriz<TYPE> X){
  29. for(unsigned i=0;i<X.filas;i++){
  30. for(unsigned j=0;j<X.columnas;j++){
  31. os<<X.datos[i][j]<<'\t';
  32. };
  33. os<<'\n';
  34. };
  35. return os;
  36. };
  37.  
  38.  
  39. int main(int argc,char* argv[]){
  40. matriz<int> A=matriz<int>(4,4);
  41. std::cout<<A<<std::endl;
  42. std::system("pause");
  43. return 0;
  44. };
  45.  


Eso o declarar y definir la sobrecarga dentro de la clase.
No lo he probado porque tengo el compilador bastante ocupado, pero si no llega a funcionar correctamente, ya sabes.

Saludos!
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Namida

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Sobre carga de operador [Visual Studio 2010]
« Respuesta #6 en: 17 Diciembre 2010, 09:40 am »

Muchas gracias Littlehorse!! El problema me ha quedado bastante claro con tu explicación. Ya probé a realizarlo de dicha forma  y va sin problemas, asi que.... ¡Problema resuelto!  ;-)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Impresión de Visual Studio 2010 Beta 2
.NET (C#, VB.NET, ASP)
Meta 0 4,302 Último mensaje 13 Noviembre 2009, 23:55 pm
por Meta
Introducing .NET 4.0 With Visual Studio 2010
.NET (C#, VB.NET, ASP)
Shell Root 3 6,091 Último mensaje 11 Febrero 2010, 19:39 pm
por Jubjub
Visual studio 2010 En ingles Disponible
.NET (C#, VB.NET, ASP)
Zeroql 2 3,858 Último mensaje 26 Abril 2010, 18:53 pm
por Zeroql
Visual Studio 2010 Help System « 1 2 »
.NET (C#, VB.NET, ASP)
Novlucker 16 14,155 Último mensaje 23 Julio 2010, 01:44 am
por Fitoschido
[Workshop/Curso] Visual Studio 2010
.NET (C#, VB.NET, ASP)
[D4N93R] 0 2,891 Último mensaje 7 Octubre 2010, 17:00 pm
por [D4N93R]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines