Salve a tutti!
Spero che qualcuno di voi possa essere così gentile da aiutarmi con questo problema.

Il mio progetto riguarda la gestione di risorse umane: uso dei template di Albero e Bst (alberi binari di ricerca) derivato da Albero; Gestionale, poi, non è altro che un Bst di RisorsaUmana.

Questo l'errore in compilazione (premetto che compilo con g++ 4) :
albero.h: In instantiation of `Albero<RisorsaUmana>':
bst.h:9: instantiated from `Bst<RisorsaUmana>'
gestionale.h:11: instantiated from here
albero.h:12: error: template-id `operator<< <RisorsaUmana>' for `std::basic_ostr
eam<char, std::char_traits<char> >& operator<<(std::basic_ostream<char, std::cha
r_traits<char> >&, const Albero<RisorsaUmana>&)' does not match any template dec
laration
bst.h: In instantiation of `Bst<RisorsaUmana>':
gestionale.h:11: instantiated from here
bst.h:10: error: template-id `operator<< <RisorsaUmana>' for `std::basic_ostream
<char, std::char_traits<char> >& operator<<(std::basic_ostream<char, std::char_t
raits<char> >&, const Bst<RisorsaUmana>&)' does not match any template declarati
on
Questo invece il codice di Albero.h (che suppongo sia il file interessato dall'errore):
codice:
#ifndef ALBERO_H
#define ALBERO_H
#include <iostream>
#include <deque>
using namespace std;

template <class T> 
class Bst;

template <class T>
class Albero {	//	Albero
friend ostream& operator<< <T>(ostream&,const Albero<T>&);
friend class Iteratore;
	protected:
		class Nodo;
		class Smartp {	//	SmartP
			public:
				Nodo* punt;
				Smartp(Nodo* p=0); //Costruttore che agisce da convertitore Nodo*->Smartp
				Smartp(const Smartp&);
				~Smartp();
				Smartp& operator=(const Smartp&);
				Nodo& operator*() const;
				Nodo* operator->() const;
				bool operator==(const Smartp&) const;
				bool operator!=(const Smartp&) const;
		};
		class Nodo {	//	Nodo
			public:
				T info;
				Nodo* par;
				int rif;
				deque<Smartp> child;
				Nodo(const T&, Nodo* p=0);
				Nodo(const Nodo&);
		};
		Smartp root;
		static Nodo* findNodo(const T&,const Smartp&); // ricorsiva, ritorna il puntatore al nodo cercato
		ostream& stampa(ostream& os,const Nodo*) const;
		static Smartp copia(const Smartp&);
		void setRoot(const Smartp&);
	public:
		class Iteratore {	//	Iteratore
			friend class Albero<T>;
			friend class Bst<T>;
			private:
				Nodo* iter;
			public:
				Iteratore(Nodo* n=0);
				bool operator==(const Iteratore&) const;
				bool operator!=(const Iteratore&) const;
				Iteratore& operator=(const Iteratore&);
				Iteratore operator++(int);	// operator ++ postfisso
				Iteratore operator++();		// operator ++ prefisso
				Nodo& operator*() const;
				Nodo* operator->() const;
		};
		bool empty() const;	//t.empty() dà TRUE se t è albero vuoto
		virtual bool insert(const T&,const T&);	//t.insert(f,p) inserisce f come figlio di qualsiasi nodo p, oppure ritorna FALSE
		virtual bool erase(const T&);	//t.erase(n) elimina da t tutti i nodi con valore n (v.modalità di cancellazione)
		void clear();	//t.clear() fa diventare t albero vuoto
		virtual Iteratore find(const T&) const;	//t.find(n) ritorna Iteratore per un qualsiasi nodo n oppure nullo
		virtual Iteratore find(const T&,const T&) const;	// t.find(n,r) ritorna Iteratore per un qualsiasi nodo con valore n nel sottoalbero radicato in r oppure nullo
		Iteratore begin() const;
		Iteratore end() const;
		T& operator[](Iteratore);
};


//---------------------------------------------------------------------------------------------
//				IMPLEMENTAZIONE METODI
//---------------------------------------------------------------------------------------------

//Costruttore di Nodo (2 parametri)
template <class T>
Albero<T>::Nodo::Nodo(const T& n,Nodo* p):info(n),par(p),rif(0){};


...
             [ CUT ]
...


template<class T>
ostream& Albero<T>::stampa(ostream& os,const Nodo* s) const{
	os<<s->info<<" { ";
	if(!s->child.empty()){
		for(int i=0;i<s->child.size();i++){
			stampa(os,s->child[i].punt);
			if(i<s->child.size()-1)
				os<<", ";
		}
	}
	os<<" }";
	return os;
};

template<class T>
ostream& operator<< (ostream& os,const Albero<T>& a){
	if(a.empty()) return os << "Albero vuoto";
	return a.stampa(os,a.root.punt);
};

#endif


Vi prego datemi voi qualche indizio!!!!


(aggiungo che, e non vorrei dire cavolate ma penso proprio sia così, se non ricordo male su compilatore g++ 3, compilava ed eseguiva correttamente)