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?
Non definire la propria macro null (o NULL o qualsiasi cosa correlata). Nel caso di inizializzazione dei membri dei dati, '0' funziona bene. –
So che è brutto, è stato solo temporaneo. Ma ero abbastanza sicuro che il C++ non permettesse il casting implicito. –
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). –