PDA

Visualizza la versione completa : [C++] template con piu` argomenti .. dubbi su overload


drudox
19-04-2012, 14:32
Salve a tutti , sto rimplementando una classe Matrix che avevo gia` implementato come template a unico argomento .. ora sto implementandola passando le sue dimensioni come argomenti del template .. ho pero` problemi con gli operatori .. ovvero operatore di assegnamento .. posto definizione , funzione operator= ed errore .. che chiaramente non capita se le matrici han uguali dimensioni .. ma proprio non so come poter scrivere il codici per matrici con dimensioni diverse (dimensioni di partenza si intende)





template< typename mType , unsigned int r ,unsigned int c>
class Matrix;


template< typename mType , unsigned int r ,unsigned int c >
std::ostream& operator<< ( std::ostream& , Matrix<mType,r,c>& );


// MATRIX TEMPLATE
//
template< typename mType , unsigned int r = 1 ,unsigned int c = 1>
class Matrix
{

template<typename T , unsigned int N , unsigned int M>
friend std::ostream& operator<< ( std::ostream& , Matrix<T,N,M>& );

public:
inline Matrix();
inline Matrix(mType);
inline Matrix(const Matrix&);
~Matrix();
inline std::vector<int> size()const;
bool resize( unsigned int , unsigned int);
void print()const ;
void initialize(mType);
mType& operator()(unsigned int , unsigned int);
Matrix& operator=(const Matrix&);

private:
unsigned int row_ ;
unsigned int column_ ;
mType **M_ ;

bool empty;
bool allocated ;
bool allocate();
bool allocate(unsigned int, unsigned int);
};


l'operatore che mi sta dando problemi e` definito cosi` :


template< typename mType, unsigned int r ,unsigned int c>
Matrix<mType,r,c>& Matrix<mType,r,c>::operator=(const Matrix<mType,r,c>& toCopy)
{
if( this == &toCopy )
std::cerr << "Autoassignment occured in operator=(const Matrix&) "
<< std::endl ;
else
{
this-> allocated = this->allocate(toCopy.row_ , toCopy.column_ );

for(unsigned int i=0; i< row_ ; i++)
for(unsigned int j=0 ; j < column_ ; j++)
this->M_ [i][j] = toCopy.M_[i][j] ;

empty = false;

return *this;

}
}



e questo e` l'errore :



main.C: In function ‘int main()’:
main.C:22:6: error: no match for ‘operator=’ in ‘A = B’
matrix.H:253:20: note: candidate is: Matrix<mType, r, c>& Matrix<mType, r, c>::operator=(const Matrix<mType, r, c>&) [with mType = double, unsigned int r = 30u, unsigned int c = 50u]







grazie per l'aiuto ;)

Who am I
19-04-2012, 14:55
Matrix <double, std::string, std::string> M;


Questo è contemplato?
Perché se non è così non serve (ed è anzi un problema) utilizzare i tipi parametrici per le dimensioni di riga e di colonna.



template< typename mType>
class Matrix;


Comunque vediamo per ora di correggere quell' errore di sintassi.A quanto pare il problema è nel main perché la dichiarazione mi sembra corretta.Puoi postare anche il codice del main?

drudox
19-04-2012, 15:11
Si se devo esser sincero le dimensioni interne sono "solo per cambiar qualcosa" pero` nascon fuori questi errori che evidenziando una mala comprensione e chiarirli non fa` mai male :) il main e` semplicissimo eccolo :



# include <iostream>

# include "matrix.H"

using namespace std;


int main()
{
Matrix<double , 30 , 50 > A ;
Matrix<double, 3 , 5> B ;

// B.print();
//cout << B.empty ;
// B.resize(30,50);
// B.initialize( 3.12 );

// B(1,2) = 3.2 ;

// cout << B(1,2) << endl ;

A = B ;

return 0;
}


Nota che i commenti erano delle prove per gli altri metodi

drudox
19-04-2012, 15:17
Comunque


Matrix <double, std::string, std::string> M;


no che non e` contemplato .. i tipi acettati sono solo degli int non dei typename ..

shodan
19-04-2012, 17:56
A prescindere dall'errore (risolvibile con una member function template), stai facendo un grosso errore concettuale: gli indici di matrice che poni sono costanti e non possono / debbono essere modificati per nessun motivo (poco importa se fai un'allocazione dinamica).
Altrimenti corri il rischio (voluto o meno) di avere una Matrix<int,10,20> che in realtà ha come limiti reali 4,3 (per esempio). E questo in virtù della funzione resize() che hai scritto.
In poche parole se vuoi usare indici costanti nel template, devi considerare la matrice di dimensioni fisse.

Grosso modo la regola aurea per i template è: un template è per sempre. :D

drudox
19-04-2012, 19:03
un template e` per sempre ? wow che intendi dire ? sempre meglio un solo parametro ?? si sul discorso delle dimensioni fisse hai pienamente ragione non ci avevo pensato .. quindi in genere le dimensioni sempre fuori dal tipo ... ;)

shodan
19-04-2012, 19:28
Originariamente inviato da drudox
un template e` per sempre ? wow che intendi dire ?
Una volta stabilito un template, quello fa da "stampino" per la generazione di codice reale.
Nel tuo caso, se stabilisci che Matrix debba avere tre parametri, puoi variare il tipo T, righe e colonne, ma sempre tre parametri devi dare. E una volta stabilito come Matrix debba essere istanziata, non puoi modificare il T, righe o colonne a runtime, ma solo variando manualmente i parametri e ricompilando. In questo senso va letto: "un template è per sempre".

Ora, di per se non è sbagliato fissare i parametri a compile time (una matrice grossa si può solo allocare nell'heap), ma un'assegnazione tra due Matrix (come vorresti fare tu) ha senso solo se la matrice da assegnare è <= della matrice in cui copiare (trattandola in effetti come sottomatrice).



sempre meglio un solo parametro ??

Dipende. Il massimo della flessibilità si ha impostando i limiti a runtime (come hai fatto fino adesso), ma nulla vieta (fermo restando quanto detto) di fissare i limiti a compile time.

drudox
19-04-2012, 19:32
ora e` chiarissimo grazie 1000 ,
e la member function template di cui parlavi ?

shodan
19-04-2012, 19:50
A memoria una cosa del genere.
Il friend è necessario per accedere ai membri interni.
Attenzione che la funzione non sarà istanziata dal compilatore finchè non verrà usata.


template< typename mType , unsigned int r = 1 ,unsigned int c = 1>
class Matrix
{

template<typename T , unsigned int N , unsigned int M>
friend std::ostream& operator<< ( std::ostream& , Matrix<T,N,M>& );

template<typename U , unsigned int Rows , unsigned int Cols>
friend class Matrix<U,Rows,Cols>;

public:
template<typename U , unsigned int Rows , unsigned int Cols>
Matrix& operator=(const Matrix<U,Rows,Cols>& );
...
}

template< typename mType , unsigned int r ,unsigned int c>
template<typename U , unsigned int Rows , unsigned int Cols>
inline Matrix<mType,r,c>& Matrix<mType,r,c>::operator=(const Matrix<U,Rows,Cols>& rhs) {
...
}

drudox
19-04-2012, 20:00
lo avevo provato .. ma senza dichiarare friend ;) grazie ancora
buona serata

Loading