Newsgroup: it.comp.lang.c++
Titolo: operator<< & template

Salve a tutti,
Ho il problema di dover implementare l'operator<< per gli stream
all'interno di una classe template. Dopo alcuni tentativi e seguendo i
messaggi del compilatore sono giunto a questa forma :
template < class T > class Prova {
	public :
	template < T > friend ostream& operator<< ( ostream& os, const
Prova<T>& p );
	private :
	T a;
};
template < class T > ostream& operator<< ( ostream& os, const
Prova<T>& p ) {
	os << p.a << '\n';
	return os;
}
int main ( ){
	Prova<int> p;
	cout << p << endl;
	return 0;
}
A questo punto però capita una cosa strana nel senso che quando
compilo il compilatore mi dice che "a" è privato all'interno del
contesto della funzione operator<<, ma avendo dichiarato tale funzione
friend perchè non posso accedere ai membri privati della classe ?
Qui di seguito riporto l'output del compilatore ( gcc 3.2 ) :
$ g++ -o Prova.exe Prova.cpp
Prova.cpp: In function `std::ostream& operator<<(std::ostream&, const 
   Prova<T>&) [with T = int]':
Prova.cpp:25:   instantiated from here
Prova.cpp:15: `int Prova<int>::a' is private
Prova.cpp:19: within this context
ringrazio anticipatamente, chiunque vorrà aiutarmi.
CoF.

 Prova<T>& p );
togli il  template<T> iniziale da qui, e qualifica l'operator << .
In altre parole stai dichiarando friend la funzione sbagliata (che non 
c'e`).
Modifica in:
template < class T >
class {
     ...
     friend ostream & operator << <T> (ostream & os, const Prova<T>& p);
};
e vedrai che funziona.
-- 
   |   \    \  | ___|_  |_  | ianezz a casa sua... :-)
   |  _ \  | \ | _|    /   /  Visita il LinuxTrent a
  _|_/  _\_|  _|____|___|___| 
http://www.linuxtrent.it

 all'interno di una classe template.
Se ne è parlato recentemente. Eccoti una versione funzionante:
#include <iostream>
template < class T > class Prova;
template < class T > std::ostream& operator<< ( std::ostream& os, const
Prova<T>& p );
template < class T > class Prova {
        public :
        friend std::ostream& operator << <> ( std::ostream& os, const
Prova<T>& p );
        private :
        T a;
};
template < class T > std::ostream& operator<< ( std::ostream& os, const
Prova<T>& p ) {
        os << p.a << '\n';
        return os;
}
int main ( ){
        Prova<int> p;
        std::cout << p << std::endl;
        return 0;
}
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 e vedrai che funziona.
No che non funziona.


 No che non funziona.
std::ostream &...


 std::ostream &...
No, non è quello il problema. Guardati l'esempio che ho mandato io.


Vi ringrazio per l'aiuto, ho corretto come mi avete suggerito e cosa
più importante mi sono accorto che non conoscevo la dichiarazione
esplicita delle funzioni template, così mi sono documentato a riguardo
ma c'è ancora una cosa che non capisco :
friend ostream& operator<< <T> ( ostream& os, const Prova<T>& p );
Questa dichiarazione mi è chiara.
friend ostream& operator<< <> ( ostream& os, const Prova<T>& p );
Questa no. Il fatto di non specificare nulla tra le due parentesi
angolari cosa sta a significare ?
Vi ringrazio ancora,
CoF.

 angolari cosa sta a significare ?
La stessa cosa di quella sopra.


 No, non è quello il problema. Guardati l'esempio che ho mandato io.
L'ho guardato attentamente: di diverso c'e` l'#include <iostream>, la 
qualificazione con std:: (e fin qui sono un pollastro) e la 
dichiarazione dei due template prima di definirli.
Il che non mi sembrava strettamente necessario, visto che quando si 
arriva a "friend" dovrebbe essere gia` accertato che Prova e` un 
template parametrizzato su T, e che in caso di istanziazione bisogera` 
andare in seguito a cercare  un template <class T> std::ostream& 
operator << (...) parametrizzato su T (visto che friend di per se` e` 
una dichiarazione e non un uso).
Forse il problema e` proprio sull'"in seguito", e son stato tratto in 
errore da compilatori troppo benevolenti rispetto allo standard? (mi 
basta un "si", se il problema e` questo).


 basta un "si", se il problema e` questo).
Scusami se ho dato l'impressione di avere le idee chiare sull'argomento.
In realtà non ce le ho affatto (a volte mi chiedo se sia possibile per
una persona normale avere qualche idea chiara sul C++...). Probabilmente
dipende dal fatto che l'operatore non è membro della classe e quindi non
dichiarandolo esplicitamente template il compilatore non lo considera
tale.
