在模板类中声明模板好友类时发生编译器错误
为了教学目的,我一直在尝试实现自己的链表类。在模板类中声明模板好友类时发生编译器错误
我在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>;
};
名单。 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:错误:所需模板参数“结构列表“
List.cc:在成员函数 '迭代一览:: createStartIterator()const的[与T = INT]':
trial.cpp:18:从这里
Iterator.h实例:14:错误:迭代::迭代器(节点*)[用T = INT]'是私人
表.cc:120:错误:在这种情况下
似乎它不认识朋友声明。 我哪里错了?
尝试在Iterator.h
开始加入预先声明
template <class T> class List;
- 这可能是你所需要的,让friend
声明Iterator
类的内部工作。
谢谢!这对我有效。 – sgowd 2015-12-05 01:01:03
问题是List没有在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
};
//...
};
不要定义您自己的null(或NULL或任何相关的)宏。在初始化数据成员的情况下,'0'工作得很好。 – 2010-01-03 00:46:15
我知道这很丑,只是暂时的。但我确信C++不允许隐式转换。 – 2010-01-03 00:48:20
演员绝不隐含,但转换是。 (您可能会说,同一枚硬币的两面,“转换”也用于命名将值转换为其他用途的方法,但这是另一种类型的转换。)需要初始化指针的另一个指针合适的类型或空指针常量; '0'是一个非常好的空指针常量(如果你愿意,'NULL'也是如此)。 – 2010-01-03 00:52:32