开发者

Compiler error in declaring template friend class within a template class

开发者 https://www.devze.com 2022-12-15 02:52 出处:网络
I have been trying to implement my own linked list class for didactic purposes. I specified the \"List\" class as friend inside the Iterator declaration, but it doesn\'t seem to compile.

I have been trying to implement my own linked list class for didactic purposes.

I specified the "List" class as friend inside the Iterator declaration, but it doesn't seem to compile.

These are the interfaces of the 3 classes I've used:

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

And this is the test program I've been trying to run:

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

When I try to compile it, the compiler gives me the following errors:

Iterator.h:26: error: ‘List’ is not a template

Iterator.h: In instantiation of ‘Iterator’:

trial.cpp:18: instantiated from here

Iterator.h:12: error: template argument required fo开发者_开发技巧r ‘struct List’

List.cc: In member function ‘Iterator List::createStartIterator() const [with T = int]’:

trial.cpp:18: instantiated from here

Iterator.h:14: error: ‘Iterator::Iterator(Node*) [with T = int]’ is private

List.cc:120: error: within this context

Seems like it is not recognizing the friend declaration. Where did I go wrong?


try adding a forward declaration

template <class T> class List;

at the start of Iterator.h -- that might be what you need to allow the friend declaration inside the Iterator class to work.


The problem is List has not been properly declared in Iterator.h. Instead, nest the Iterator class inside List (automagically making it a template), which you'll likely want to do anyway (to use List::Iterator instead of renaming it to ListIterator or IteratorForList, as you would to have more than one Iterator in a namespace).

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

精彩评论

暂无评论...
验证码 换一张
取 消