Cita de: amchacon en 16 Diciembre 2013, 18:07 PMPues me he puesto a estudiar y implementar los templates en la clase, pero me he encontrado con un problema que no me deja avanzar. La mayoría de mis sobrecargas de operadores son funciones amigas de la función, y por lo visto en general hay problemas al implementar los templates con funciones amigas. No sé si por suerte o por desgracia, la única función que parece no encajar bien con los templates es la de sobrecarga del producto. A ver si me podéis ayudar con esto, que llevo un buen rato peleándome con el error buscando, moviendo y cambiando código... Pero no lo consigo.
char es un dato número, es como si fuera un int de 1 byte.
No hay ningún problema mientras la clase que use tenga definido los operadores correspondientes (+ - * / ==...).
O al menos tenga definido los operadores de las funciones que vaya a usar.
Vuelvo a pegar el código entero de la clase (ya que se han tenido que cambiar bastantes cosas) y el mensaje de error que estoy recibiendo:
Matriz.h:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;
template <class T>
class Matriz {
private:
int nfilas;
int ncolumnas;
T **matr = NULL;
void borrar();
public:
//Constructora
Matriz(int filas, int columnas);
//Constructora-copiadora
Matriz(const Matriz<T> &m);
//Destructora
~Matriz();
//Consultoras
int filas() const;
int columnas() const;
T consultar(int fila, int columna) const;
//Modificadora
void modificar(int fila, int columna, T x);
//Operadores
Matriz& operator =(const Matriz<T> &b);
void operator +=(const Matriz<T> &mat);
void operator -=(const Matriz<T> &mat);
friend Matriz operator + <>(const Matriz<T> &a, const Matriz<T> &b);
friend Matriz operator - <>(const Matriz<T> &a, const Matriz<T> &b);
friend Matriz operator * <>(const Matriz<T> &a, const Matriz<T> &b);
friend Matriz operator * <>(const Matriz<T> &a, int b);
friend Matriz operator * <>(int a, const Matriz<T> &b);
friend bool operator == <>(const Matriz<T> &a, const Matriz<T> &b);
friend bool operator != <>(const Matriz<T> &a, const Matriz<T> &b);
friend ostream& operator << <>(ostream &salida, const Matriz<T> &mat);
friend istream& operator >> <>(istream &entrada, Matriz<T> &mat);
};
template <class T>
Matriz<T>::Matriz(int filas = 0, int columnas = 0) : nfilas(filas), ncolumnas(columnas)
{
if (nfilas > 0 and ncolumnas > 0)
{
matr = new T* [filas];
for (int i = 0; i < filas; ++i) matr[i] = new T [columnas];
}
}
template <class T>
Matriz<T>::Matriz(const Matriz<T> &m) { *this = m; }
template <class T>
Matriz<T>::~Matriz() { borrar(); }
template <class T>
void Matriz<T>::borrar()
{
if (this->matr != NULL)
{
for (int i = 0; i < nfilas; ++i) delete[] matr[i];
delete[] matr;
matr = NULL;
}
}
template <class T>
int Matriz<T>::filas() const { return nfilas;}
template <class T>
int Matriz<T>::columnas() const { return ncolumnas;}
template <class T>
T Matriz<T>::consultar(int fila, int columna) const { return matr[fila][columna];}
template <class T>
void Matriz<T>::modificar(int fila, int columna, T x) { matr[fila][columna] = x;}
template <class T>
Matriz<T>& Matriz<T>::operator =(const Matriz<T> &mat)
{
if (this != &mat)
{
this->borrar();
if (mat.matr)
{
this->nfilas = mat.nfilas;
this->ncolumnas = mat.ncolumnas;
this->matr = new int* [nfilas];
for (int i = 0; i < nfilas; ++i)
this->matr[i] = new int [ncolumnas];
for (int i = 0; i < nfilas; ++i)
{
for (int j = 0; j < ncolumnas; ++j)
this->matr[i][j] = mat.matr[i][j];
}
}
}
return *this;
}
template <class T>
void Matriz<T>::operator +=(const Matriz<T> &mat)
{
if (this->nfilas != 0 and this->ncolumnas != 0 and mat.nfilas != 0 and mat.ncolumnas != 0)
{
for (int i = 0; i < nfilas; ++i)
for (int j = 0; j < ncolumnas; ++j)
this->matr[i][j] += mat.matr[i][j];
}
}
template <class T>
void Matriz<T>::operator -=(const Matriz<T> &mat)
{
if (this->nfilas != 0 and this->ncolumnas != 0 and mat.nfilas != 0 and mat.ncolumnas != 0)
{
for (int i = 0; i < nfilas; ++i)
for (int j = 0; j < ncolumnas; ++j)
this->matr[i][j] -= mat.matr[i][j];
}
}
template <class T>
Matriz<T> operator +(const Matriz<T> &a, const Matriz<T> &b)
{
int filas = a.nfilas;
int columnas = a.ncolumnas;
Matriz<T> res(filas, columnas);
for (int i = 0; i < filas; ++i)
for (int j = 0; j < columnas; ++j)
res.matr[i][j] = a.matr[i][j] + b.matr[i][j];
return res;
}
template <class T>
Matriz<T> operator -(const Matriz<T> &a, const Matriz<T> &b)
{
int filas = a.nfilas;
int columnas = a.ncolumnas;
Matriz<T> res(filas, columnas);
for (int i = 0; i < filas; ++i)
for (int j = 0; j < columnas; ++j)
res.matr[i][j] = a.matr[i][j] - b.matr[i][j];
return res;
}
template <class T>
Matriz<T> operator *(const Matriz<T> &a, const Matriz<T> &b)
{
if (a.ncolumnas == b.nfilas)
{
int pos = a.ncolumnas;
int filas = a.nfilas;
int columnas = b.ncolumnas;
Matriz<T> res(filas, columnas);
for (int i = 0; i < filas; ++i)
{
for (int j = 0; j < columnas; ++j)
{
int value = 0;
for (int k = 0; k < pos; ++k) value += a.matr[i][k] * b.matr[k][j];
res.matr[i][j] = value;
}
}
return res;
}
}
template <class T>
Matriz<T> operator *(const Matriz<T> &a, int b)
{
int filas = a.nfilas;
int columnas = a.ncolumnas;
Matriz<T> res(filas, columnas);
for (int i = 0; i < filas; ++i)
for (int j = 0; j < columnas; ++j) res.matr[i][j] = a.matr[i][j] * b;
return res;
}
template <class T>
Matriz<T> operator *(int a, const Matriz<T> &b) { return b*a; }
template <class T>
bool operator ==(const Matriz<T> &a, const Matriz<T> &b)
{
if (a.nfilas != b.nfilas or a.ncolumnas != b.ncolumnas) return false;
for (int i = 0; i < a.nfilas; ++i)
for (int j = 0; j < a.ncolumnas; ++j)
if (a.matr[i][j] != b.matr[i][j]) return false;
return true;
}
template <class T>
bool operator !=(const Matriz<T> &a, const Matriz<T> &b) { return !(a == b); }
template <class T>
ostream& operator <<(ostream &salida, const Matriz<T> &mat)
{
for (int i = 0; i < mat.nfilas; ++i)
{
for (int j = 0; j < mat.ncolumnas; ++j) salida << mat.matr[i][j] << " ";
salida << endl;
}
return salida;
}
template <class T>
istream& operator >>(istream &entrada, Matriz<T> &mat)
{
for (int i = 0; i < mat.nfilas; ++i)
for (int j = 0; j < mat.ncolumnas; ++j) entrada >> mat.matr[i][j];
return entrada;
}
Y el error que recibo al compilar la clase es el siguiente:
Código [Seleccionar]
Matriz.h:43:26: error: declaration of 'operator*' as non-function
Matriz.h:43:26: error: expected ';' at end of member declaration
Matriz.h:43:28: error: expected unqualified-id before '<' token
Matriz.h:44:26: error: declaration of 'operator*' as non-function
Matriz.h:44:26: error: expected ';' at end of member declaration
Matriz.h:44:28: error: expected unqualified-id before '<' token
Matriz.h:45:26: error: declaration of 'operator*' as non-function
Matriz.h:45:26: error: expected ';' at end of member declaration
Matriz.h:45:28: error: expected unqualified-id before '<' token
Como podéis ver he añadido "<>" al final del nombre de cada función amiga de la clase, ya que buscando solución a un problema anterior he visto que la mayoría de códigos implementaban esa metodología para las funciones amigas de la clase. Hay más información sobre ésto aquí: http://c.conclase.net/curso/?cap=040c#042_amigaplantilla
Tampoco descarto que os encontréis alguna que otra barbaridad con los templates
Gracias por la ayuda! ^^