Я пытался реализовать свой собственный класс связанного списка в дидактических целях.
Я определил класс "Списка" как друга в объявлении Итератора, но это, кажется, не компилирует.
Это интерфейсы этих 3 классов, которые я использовал:
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&);
};
И это - тестовая программа, которую я пытался выполнить:
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;
}
Когда я пытаюсь скомпилировать его, компилятор дает мне следующие ошибки:
Итератор h:26: ошибка: 'Список' не является шаблоном
Iterator.h: В инстанцировании 'Итератора':
пробная версия cpp:18: инстанцированный отсюда
Итератор h:12: ошибка: аргумент шаблона требуется для ‘Списка структуры’
List.cc: В функции членства ‘Список Итератора:: createStartIterator () константа [с T = интервал]’:
пробная версия cpp:18: инстанцированный отсюда
Итератор h:14: ошибка: ‘Итератор:: Итератор (Узел*) [с T = интервал]’ является частным
Список cc:120: ошибка: в этом контексте
Кажется, что это не распознает друга объявление. Где я шел не так, как надо?
попробуйте добавить прямое объявление
template <class T> class List;
в начале Iterator.h
-- это может быть то, что вам нужно, чтобы friend
объявление внутри класса Iterator
заработало.
Проблема в том, что в Iterator.h не был правильно объявлен "Список". Вместо этого, вложите класс Iterator внутри List (автоматически делая его шаблоном), что вы, вероятно, захотите сделать в любом случае (использовать List::Iterator вместо того, чтобы переименовывать его в ListIterator или IteratorForList, так как вы должны иметь более одного Iterator в пространстве имён).
template<class T>
struct List {
//...
struct Node {/*...*/};
struct Iterator {
// ...
private:
Iterator(Node*);
friend class List; // still required
};
//...
};