Newsgroup: it.comp.lang.c++
Titolo: Templates e ostreams

Salve a tutti,
ho definito una classe template e vorrei ridefinire l'operatore << per gli
oggetti di tale classe. Se definisco l'operatore come inline non ci sono
problemi, ma se voglio definirlo come non-inline, non riesco a capire quale
sia la sintassi giusta. Il codice del problema ridotto all'osso è il
seguente:
#include <iostream.h>
template<class T> class Classe
{
public:
 Classe(T el) { elemento=el; };
 friend ostream& operator<<(ostream& os, const Classe<T> & C) { return os <<
C.elemento; };
private:
 T elemento;
};
main()
{
 Classe<int> A(2); cout << A;
}
Il codice della funzione non-inline, a mio avviso, dovrebbe essere definito
come segue:
template<class T> ostream& operator<<(ostream& os, const Classe<T> & C)
{
 return os << C.elemento;
}
La compilazione funziona, però il linker protesta perché non trova il
riferimento all'istanza di << voluta. L'errore è il seguente:
Error: Unresolved external 'operator <<(std::basic_ostream<char,
std::char_traits<char> >&, const Classe<int>&)' referenced from
C:\PROGRAMMAZIONE\CPP\TEST.OBJ
Mi serve effettivamente poter definire tale operatore come funzione
non-inline in quanto devo poi usare dei cicli for, che tipicamente generano
warning nelle funzioni inline.
Qual è la sintassi da adoperare?
Grazie
Davide

Due ipotesi: per prima cosa il codice della versione out of line del
template deve comunque essere visibile dove il template viene
utilizzato: mi aspetto che sia nello stesso sorgente o che venga
incluso.
In secondo luogo potresti provare a dichiarare la funzione prima della
classe in cui e' dichiarata friend (o a spostarne l'implementazione
prima della classe che la dichiara friend); teoricamente non potresti
dichiarare friend una classe o funzione che non e' ancora stata
dichiarata o definita.
Ciao,
Nicola

  friend ostream& operator<<(ostream& os, const Classe<T> & C) ;
con
template <class J>
friend ostream& operator<<(ostream& os, const Classe<J> & C) ;
Praticamente la classe "Classe" e' amica di tutt i template di operator<< ..
Non mi convince molto ma almeno cosi il g++ non si lamenta ..

Avevo già provato a ripetere "friend" anche nella definizione off-line, ma
il compilatore bcc5.5 della borland (che risponde sicuramente a tutti gli
standard attuali) dà errore:
Error E2092 test.cpp 13: Storage class 'friend' is not allowed here
*** 1 errors in Compile ***
Forse non ho capito la tua osservazione, comunque il codice sorgente
completo cui mi riferisco è così fatto:
#include <iostream.h>
template<class T> class Classe
{
public:
 Classe(T el) { elemento=el; };
 friend ostream& operator<<(ostream& os, const Classe<T> & C);
private:
 T elemento;
};
// definizione off-line: non vuole la parola "friend" qui
template<class T> friend ostream& operator<<(ostream& os, const Classe<T> &
C)
{
 return os << C.elemento;
}
main(void)


 standard attuali)
Che io sappia NON ESISTE un compilatore 100% compliant! E anche fra i "quasi
compliant" di certo il BCC non e' uno di quelli piu' vicini allo standard.
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

A questo proposito vi consiglio di consultare l'articolo di Herb Sutter "C++
conformance roundup" su 
http://www.cuj.com/roundup/a.htm
, segnalato da
Nicola (mi pare!).
Lello
