J'ai essayé d'implémenter ma propre classe de liste chaînée à des fins didactiques.Erreur de compilation lors de la déclaration d'une classe d'ami modèle dans une classe modèle
J'ai spécifié la classe "List" comme ami dans la déclaration Iterator, mais il ne semble pas compiler.
Ce sont les interfaces des 3 classes que j'ai utilisé:
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>;
};
Liste. 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&);
};
C'est le programme de test que j'ai essayé de courir:
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;
}
Lorsque je tente de le compiler, le compilateur me donne les erreurs suivantes :
Iterator.h: 26: erreur: 'List' est pas un modèle
Iterator.h: Dans instanciation 'itérateur':
trial.cpp: 18: instancié d'ici
Iterator.h: 12: Erreur: argument modèle requis pour « Liste struct '
List.cc: en fonction membre 'Iterator :: Liste createStartIterator() const [avec T = int]':
trial.cpp: 18: instancié d'ici
Iterator.h: 14: Erreur: 'Iterator :: iterator (Noeud *) [avec T = int]' est privé
Liste .cc: 120: erreur: dans ce contexte
On dirait qu'il ne reconnaît pas la déclaration d'ami. Où est-ce que je me suis trompé?
Ne définissez pas votre propre macro null (ou NULL, ou n'importe quoi d'autre). Dans le cas de l'initialisation des membres de données, '0' fonctionne très bien. –
Je sais que c'est moche, c'était seulement temporaire. Mais j'étais tout à fait sûr que C++ n'autorisait pas le casting implicite. –
Les lancers ne sont jamais implicites, mais les conversions le sont. (Deux côtés de la même pièce, vous pourriez dire, et "conversion" est également utilisé pour nommer des méthodes qui convertissent une valeur parmi d'autres utilisations, mais c'est un type différent de conversion.) Ce que vous devez initialiser un pointeur est un autre pointeur type approprié ou une constante de pointeur nulle; '0' est une constante de pointeur null parfaitement fine (' NULL' est aussi, si vous préférez). –