2010-01-03 13 views
12

Ho cercato di implementare la mia propria classe di elenchi collegati a scopo didattico.Errore del compilatore nel dichiarare il modello friend class all'interno di una classe template

ho specificato la classe "List" come amico all'interno della dichiarazione Iterator, ma non sembra per la compilazione.

Queste sono le interfacce delle 3 classi che ho usato:

Node.h:

#define null (Node<T> *) 0 

template <class T> 
class Node { 
public: 
    T content; 
    Node<T>* next; 
    Node<T>* prev; 

    Node (const T& _content) : 
     content(_content), 
     next(null), 
     prev(null) 
    {} 
}; 

Iterator.h:

#include "Node.h" 

template <class T> 
class Iterator { 
private: 
    Node<T>* current; 

    Iterator (Node<T> *); 

public: 
    bool isDone() const; 

    bool hasNext() const; 
    bool hasPrevious() const; 
    void stepForward(); 
    void stepBackwards(); 

    T& currentElement() const; 

    friend class List<T>; 
}; 

List. h

#include <stdexcept> 
#include "Iterator.h" 

template <class T> 
class List { 
private: 
    Node<T>* head; 
    Node<T>* tail; 
    unsigned int items; 

public: 
    List(); 

    List (const List<T>&); 
    List& operator = (const List<T>&); 

    ~List(); 

    bool isEmpty() const { 
     return items == 0; 
    } 
    unsigned int length() const { 
     return items; 
    } 
    void clear(); 

    void add (const T&); 
    T remove (const T&) throw (std::length_error&, std::invalid_argument&); 

    Iterator<T> createStartIterator() const throw (std::length_error&); 
    Iterator<T> createEndIterator() const throw (std::length_error&); 
}; 

E questo è il programma di test che ho cercato di correre:

trial.cpp

using namespace std; 
#include <iostream> 
#include "List/List.cc" 

int main() 
{ 
List<int> myList; 

for (int i = 1; i <= 10; i++) { 
    myList.add(i); 
} 

for (Iterator<int> it = myList.createStartIterator(); !it.isDone(); it.stepForward()) { 
    cout << it.currentElement() << endl; 
} 

return 0; 
} 

Quando provo a compilarlo, il compilatore mi dà i seguenti errori :

Iterator.h: 26: errore: 'Lista' non è un modello

Iterator.h: In istanza di 'Iterator':

trial.cpp: 18: istanziato da qui

Iterator.h: 12: errore: template argomento richiesto per 'Lista struct '

List.cc: In funzione membro 'Iterator List :: createStartIterator() const [con T = int]':

trial.cpp: 18: istanziato da qui

Iterator.h: 14: errore: 'Iterator :: Iterator (Nodo *) [con T = int]' è privato

Lista .cc: 120: errore: in questo contesto

sembra che non riconosce la dichiarazione amico. Dove ho sbagliato?

+0

Non definire la propria macro null (o NULL o qualsiasi cosa correlata). Nel caso di inizializzazione dei membri dei dati, '0' funziona bene. –

+0

So che è brutto, è stato solo temporaneo. Ma ero abbastanza sicuro che il C++ non permettesse il casting implicito. –

+0

I cast non sono mai impliciti, ma le conversioni sono. (Due lati della stessa moneta, si potrebbe dire, e "conversion" è anche usato per denominare metodi che convertono un valore tra altri usi, ma questo è un diverso tipo di conversione). Quello che serve per inizializzare un puntatore è un altro puntatore di tipo adatto, o una costante di puntatore nullo; '0' è una costante del puntatore nullo perfettamente fine (anche se è NULL', se preferisci). –

risposta

15

prova ad aggiungere una dichiarazione anticipata

template <class T> class List; 

all'inizio di Iterator.h - che potrebbe essere ciò che è necessario per consentire la dichiarazione friend all'interno della classe Iterator al lavoro.

+0

Grazie! Questo ha funzionato per me. – sgowd

5

Il problema è List non è stato debitamente dichiarato in Iterator.h. Invece, annida la classe Iterator all'interno di List (rendendolo automaticamente un modello), che probabilmente vorrai comunque fare (usare List :: Iterator invece di rinominarlo in ListIterator o IteratorForList, come se avessi più di un Iterator in un namespace).

template<class T> 
struct List { 
    //... 
    struct Node {/*...*/}; 
    struct Iterator { 
    // ... 
    private: 
    Iterator(Node*); 
    friend class List; // still required 
    }; 
    //... 
}; 
Problemi correlati