在模板类中声明模板友元类时编译器错误

时间:2010-01-03 00:39:13

标签: c++ templates compiler-errors friend

我一直在努力实现我自己的链表类用于教学目的。

我在Iterator声明中将“List”类指定为朋友,但它似乎没有编译。

这些是我使用过的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;
}

当我尝试编译它时,编译器给出了以下错误:

Iterator.h:26:错误:'列表'不是模板

Iterator.h:实例化“迭代器”:

trial.cpp:18:从此处实例化

Iterator.h:12:错误:'struct List'需要模板参数

List.cc:在成员函数'Iterator List :: createStartIterator()const [with T = int]':

trial.cpp:18:从此处实例化

Iterator.h:14:错误:'Iterator :: Iterator(Node *)[with T = int]'是私有的

List.cc:120:错误:在此上下文中

似乎没有认出朋友声明。 我哪里出错了?

2 个答案:

答案 0 :(得分:15)

尝试添加前向声明

template <class T> class List;

Iterator.h的开头 - 您可能需要允许friend类中的Iterator声明工作。

答案 1 :(得分:5)

问题是List未在Iterator.h中正确声明。相反,将Iterator类嵌套在List中(自动使其成为模板),无论如何你都可能想做(使用List :: Iterator而不是将其重命名为ListIterator或IteratorForList,因为你有多个迭代器)在命名空间中。)

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