PDA

Visualizza la versione completa : [C++] Template e friend ostream e istream


December_
22-08-2011, 11:59
Se ho questa classe template con queste funzioni friend all'interno:



template<class T> class array
{

friend ostream& operator<< (ostream&,const array<T> );
friend istream& operator>> (istream&,array<T>& ) ;
};


E ricevo questi warning:

29 D:\Documenti\Template.cpp [Warning] friend declaration `std::ostream& operator<<(std::ostream&, array<T>)' declares a non-template function
30 D:\Documenti\Template.cpp [Warning] friend declaration `std::istream& operator>>(std::istream&, array<T>& )' declares a non-template function
29 D:\Documenti\Template.cpp [Warning] (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning

Che cosa dovrei fare? Ho capito che dovrei aggiungere <> prima del nome della funzione, e poi che "-Wno-non-template-friend" disabilita questi warning, ma non so dove metterlo...

Se faccio solo la prima cosa, quella delle <>, aumentano gli errori altro che risolversi!

shodan
22-08-2011, 19:53
Originariamente inviato da December_
Che cosa dovrei fare?

Personalmente preferisco evitare il ginepraio di cui sotto, scrivendo direttamente il codice della funzione nel corpo della classe. Altrimenti:


// Forward declaration
template<class T> class array;

// Dichiarazione prototipi
template <class T>
friend ostream& operator<< (ostream&,const array<T> );

template <class T>
friend istream& operator>> (istream&,array<T>& ) ;

// Definizione classe.
template<class T> class array
{

friend ostream& operator<< (ostream&,const array<T>& );
friend istream& operator>> (istream&,array<T>& ) ;
};

// Definizione delle funzioni friend.
template <class T>
friend ostream& operator<< (ostream&,const array<T> ) {
/* corpo funzione */
}

friend istream& operator>> (istream&,array<T>& ) {
/* corpo funzione */
}

MItaly
22-08-2011, 20:18
Che poi, io non ho mai capito 'sta mania di rendere friend gli operatori di inserimento ed estrazione da stream... in fin dei conti, non è altro che un modo per scrivere/leggere delle proprietà della classe, e salvo casi eccezionali queste dovrebbero essere già leggibili/scrivibili tramite metodi public, e che quindi sarebbero accessibili ad operator>> e operator<< anche se questi ultimi non fossero friend.

December_
22-08-2011, 21:25
MiItaly ti assicuro che lo eviterei volentieri se non fosse nelle richieste, dato tutti gli errori che mi dà...

Grazie per le risposte, appena ho tempo provo a cambiare il codice come detto.

MItaly
23-08-2011, 01:49
Originariamente inviato da December_
MiItaly ti assicuro che lo eviterei volentieri se non fosse nelle richieste, dato tutti gli errori che mi dà...

Nono, ma io non ce l'ho con te, dico che la vedo come tendenza generale dei corsi e dei libri di C++ e non ne capisco il motivo (cioè, in parte lo capisco, ma secondo me è sbagliato e inutile).

P.S.: MItaly, non MiItaly. :)

December_
23-08-2011, 19:07
Nono, ma io non ce l'ho con te, dico che la vedo come tendenza generale dei corsi e dei libri di C++ e non ne capisco il motivo (cioè, in parte lo capisco, ma secondo me è sbagliato e inutile). P.S.: MItaly, non MiItaly.

Perdona MItaly, distrazione, comunque sono d'accordo con la tua opinione.


Personalmente preferisco evitare il ginepraio di cui sotto, scrivendo direttamente il codice della funzione nel corpo della classe. Altrimenti:

Mettendo il codice all'interno, sembra funzionare ;) ! Grazie mille.

December_
24-08-2011, 12:08
Mentre per fare la sovrapposizione di operatori come += e ==, devo aggiungere qualcosa di particolare per le classi template?

Perchè in compilazione è tutto liscio, durante l'esecuzione cioè quando è il momento di usarli effettivamente, no. "no match for operator..."

Le funzione per la sovrapposizione le ho implementate come ho sempre fatto, solo che io le usavo per classi "normali" - e funzionavano.

shodan
24-08-2011, 12:33
Originariamente inviato da December_
Mentre per fare la sovrapposizione di operatori come += e ==, devo aggiungere qualcosa di particolare per le classi template?

Se le dichiari e definisci nel corpo della classe, no. Ma dovresti mostrare il codice.

December_
24-08-2011, 12:38
Originariamente inviato da shodan
Se le dichiari e definisci nel corpo della classe, no. Ma dovresti mostrare il codice.

Vorrei evitare in effetti di definire tutto all'interno...




//dichiarazione all'interno della classe
T* operator+= (T*);

//implementazione
template<class T> T* array<T>::operator+=(T* A){
for(int i=0; i<A.size; i++)
this->vettore[this->size+i] = A.vettore[i];

return this->vettore;
}


Errore:

180 D:\Documenti\Template.cpp no match for 'operator+=' in 'B += A'
note D:\Documenti\Template.cpp:136 candidates are: T* array<T>::operator+=(T*) [with T = int]

shodan
24-08-2011, 12:54
Originariamente inviato da December_
Vorrei evitare in effetti di definire tutto all'interno...

180 D:\Documenti\Template.cpp no match for 'operator+=' in 'B += A'
note D:\Documenti\Template.cpp :136 candidates are: T* array<T>::operator+=(T*) [with T = int]

Non puoi nemmeno mettere il codice template in un file cpp e compilarlo però.
Dovresti spostare l'implementazione nel file .h e renderla inline.
Nota che operator+= è un operatore che è obbligatorio sia membro della classe, per cui ti eviti tutto il ginepraio, ma essendo template non può essere stare in un file.cpp.

Loading