Autor
|
Tema: C++ Sobrecarga de un operador por medio de un template? (Leído 5,151 veces)
|
GisiNA
Desconectado
Mensajes: 30
|
Hola a todos! Estoy tratando de aprender por mi misma los elementos básicos de C++. He buscado en la web una respuesta a la siguiente duda, pero no la he hallado. Quizás este problema no tiene solución. Es posible traspasar un operador a un template de modo tal que el operador no solamente sea sobrecargado sino que a la vez sea reemplazado por otro, y de ese modo no sea necesario tener que repetir el mismo código solo por cambiar la operación, o sea, algo como esto: Num operator +(const Num &p1,const Num &p2) { Num erg; erg.a = p1.a + p2.a; erg.b = p1.b + p2.b; return erg; } Num operator *(const Num &p1,const Num &p2) { Num erg; erg.a = p1.a * p2.a; erg.b = p1.b * p2.b; return erg; } Num operator -(const Num &p1,const Num &p2) { Num erg; erg.a = p1.a - p2.a; erg.b = p1.b - p2.b; return erg; }
etc.... A continuación les dejo el código. Es uno sencillo del que muchos similares pueden encontrarse en libros y en la web: #include <iostream> using namespace std; class Num { public: double a, b; }; Num operator +(const Num &p1,const Num &p2) { Num erg; erg.a = p1.a + p2.a; erg.b = p1.b + p2.b; return erg; } int main() { Num num1; num1.a=1; num1.b=75; Num num2; num2.a=150; num2.b=175; Num num1und2 = num1 + num2; cout << "num1 " << "a: " << num1.a << ", b: " << num1.b << endl; cout << "num2 " << "a: " << num2.a << ", b: " << num2.b << endl; cout << "num1und2 " << "a: " << num1und2.a << ", b: " << num1und2.b << endl; return 0; }
Ese código me gustaría poder reescribir más o menos como sigue, de modo que sea posible traspasar al templete el operador: #include <iostream> using namespace std; class Num { public: double a, b; }; template<operator op> // * Algo por este estilo Num operator op(const Num &p1,const Num &p2) { Num erg; erg.a = p1.a op p2.a; // * Donde dice op que sea reemplazado por el operador deseado erg.b = p1.b op p2.b; // * Donde dice op que sea reemplazado por el operador deseado return erg; } int main() { Num num1; num1.a=1; num1.b=75; Num num2; num2.a=150; num2.b=175; Num num1und2 = num1 + num2; // * Modificando acá el operador que cambie arriba la operación cout << "num1und2 " << "a: " << num1und2.a << ", b: " << num1und2.b << endl; return 0; }
Es posible realizar una hazaña de ese tipo?
|
|
« Última modificación: 8 Mayo 2017, 01:41 am por GisiNA »
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Tienes hecha mal la sobrecarga. A parte de eso puedes hacer uso de algo más primitivo que las plantillas: el preprocesador. Un ejemplo de cómo hacerlo sería así: #include <iostream> using namespace std; class Num { public: double a, b; /* Dentro del mismo objeto, o en el archivo de implementación * preparo una macro que contendrá el código al que solo deberé * pasarle el operador que quiero. Pero cuidado pues el operador * deberá ser compatible. Solo sirve para ahorrar código. */ #define SET_OP(op) \ Num operator op(const Num &p) \ { \ Num erg; \ erg.a = a op p.a; \ erg.b = b op p.b; \ return erg; \ } // Hora de usar la macro con cada uno de los operadores. SET_OP(+); SET_OP(-); SET_OP(*); SET_OP(/); /* Elimino el símbolo de la macro por si quiero usarla más * adelnate con otros operadores u otro tipo de dato. */ #undef SET_OP }; int main() { Num num1; num1.a=1; num1.b=75; Num num2; num2.a=150; num2.b=175; Num num1und2 = num1 + num2; // * Modificando acá el operador que cambie arriba la operación cout << "num1und2 " << "a: " << num1und2.a << ", b: " << num1und2.b << endl; return 0; }
|
|
|
En línea
|
|
|
|
GisiNA
Desconectado
Mensajes: 30
|
Hola! Muchas gracias por tu respuesta! Está muy bueno! Sin embargo, tengo el interés de saber si existe la posibilidad de hacer lo mismo sobrecargando operadores usando templates. Es un interés personal, pues, no he hallado una solución en la web ni en los libros de los que dispongo. Quisiera saber si existe un método de esa manera, o si no es posible hacerlo de esa manera. Mi segunda consulta va en relación al comentario "Tienes hecha mal la sobrecarga." Sobre qué base se levanta tu comentario? Saludos!
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Si miras los errores que lanza el compilador, para el código que tienes, dice: cpp.cpp:10:47: error: ‘Num Num::operator+(const Num&, const Num&)’ must take either zero or one argument Num operator +(const Num &p1,const Num &p2)
Esta sobrecarga, dice el compilador, solo puede tener ningún o un solo argumento. A partir de aquí, una búsqueda rápida por internet te lleva al código correcto para estas sobrecargas.
De todas formas no creo que te deje hacer lo que quieres porqué las plantillas son para adaptar las variables y lo que buscas es adaptar el nombre de un método.
|
|
« Última modificación: 8 Mayo 2017, 02:28 am por MAFUS »
|
En línea
|
|
|
|
GisiNA
Desconectado
Mensajes: 30
|
Bah... a mi me compila muy bien y arroja el resultado esperado. No sabría decirte el porqué en tu caso no compila.
Ahora bien, de regreso a mi consulta..., sabes quizás si es posible realizar lo que describo?
Saludos!
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
No deben existir templates para operadores. El hecho es que una sobrecarga de operadores, a vistas de código intermedio, son funciones y no tipos de datos. Los templates existen para adaptar tipos de datos a funciones y hacerlas genéricas. Como tu idea es cambiar a qué función llamar según el operador que quieres pasar la única forma que se me ocurre es mediante el preprocesador.
|
|
|
En línea
|
|
|
|
GisiNA
Desconectado
Mensajes: 30
|
Ohhhh! Entiendo! Muy buena respuesta! Gracias!!
|
|
|
En línea
|
|
|
|
CalgaryCorpus
|
Una solucion alternativa a usar macros, pero que tampoco es exactamente lo que buscas, es usar functors. Se trata de clases o structs que tienen un metodo operator() y que puede ser redefinido en otras clases. Es eso lo que hice en el codigo que incluyo aqui: #include <functional> #include <iostream> using namespace std; // tu clase Num, con metodos adicionales para hacer mas corto el resto class Num { public: double a, b; Num(double x, double y) : a(x), b(y) {} void show() { cout << a << ":" << b << endl; } }; // la definicion del functor struct Operador : public binary_function<Num,Num,Num> { virtual Num operator()(Num&n1, Num& n2) = 0; }; // los operadores struct Sumador : public Operador { Num operator() (Num& n1, Num& n2) {return Num(n1.a+n2.a,n1.b+n2.b);} } sumador; struct Multiplicador : public Operador { Num operator() (Num& n1, Num& n2) {return Num(n1.a*n2.a,n1.b*n2.b);} } multiplicador; // definir otros, si se quiere ... // una funcion que aplica los operadores Num apply_op(Num n1, Num n2, Operador& op) { return op(n1, n2); } int main() { Num num1(1,2), num2(3,4); apply_op(num1, num2, sumador).show(); apply_op(num1, num2, multiplicador).show(); // en vez de hacer .show(), como arriba, se puede asignar el resultado, si se quiere Num resultado = apply_op( num1, num2, sumador ); resultado.show(); return 0; }
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Duda con sobrecarga de operador ( )
Programación C/C++
|
Akai
|
6
|
4,664
|
16 Noviembre 2010, 14:53 pm
por Akai
|
|
|
sobrecarga de operador<<
Programación C/C++
|
adam96
|
5
|
4,576
|
17 Diciembre 2010, 19:10 pm
por Littlehorse
|
|
|
Problema con la sobrecarga del operador <<
Programación C/C++
|
Lord_Lobotomi
|
2
|
2,436
|
5 Diciembre 2011, 19:36 pm
por Lord_Lobotomi
|
|
|
[?] Necesito ayuda con sobrecarga de operador +=
Programación C/C++
|
solinac
|
1
|
1,809
|
25 Noviembre 2013, 20:57 pm
por do-while
|
|
|
Sobrecarga operador +
Programación C/C++
|
_Enko
|
4
|
2,658
|
6 Febrero 2015, 14:56 pm
por _Enko
|
|