PDA

Visualizza la versione completa : [C++] Problema OPERATOR << e TEMPLATE


Liunai
06-08-2007, 11:39
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):


#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!!!! :dhò:


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

Liunai
06-08-2007, 17:39
Nessuna idea? :(

shodan
06-08-2007, 18:17
Manca la forward declaration (come descritto sul Thinking in C++ vol 2)




template <class T>
class Bst;

// forward declaration
template <class T> ostream& operator<< (ostream&, const const Albero<T>&);

template <class T>
class Albero { // Albero
friend ostream& operator<< <>(ostream&,const Albero<T>&); // senza T

...

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);
};



oppure meglio ancora, incorporare direttamente la funzione nella classe




template <class T>
class Bst;

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

Liunai
07-08-2007, 10:13
FANTASTICO!!! :yuppi:

Ti ringrazio moltissimo, shodan, gentilissimo e rapidissimo!

Era una cosa semplice alla fine, eppure mi sono scervellato due giorni per venirne a capo :dhò:

Grazie ancora :)

Loading