"class template has already been declared as a non-class template"链接列表模板的错误



我正试图在Visual Studio中创建一个链接列表模板;类模板已经被声明为非类模板";错误我有一个包含声明的头文件和一个包含定义的LinkList.tem文件。我在头文件的末尾#include LinkList.tem,以便对其进行编译。我有一个这样做的例子,效果很好。我已经用我的链接列表文件尽可能地复制了这个例子,但我仍然收到了错误。

LinkList.h

#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include "Node.h"
template <typename T>
class LinkList { // This line is where I get the error
public:
LinkList() { first = last = nullptr; } // empty container
// value Semantic Functions
// copy constructor
LinkList(const LinkList<T>& source);
// assignment operator
LinkList<T>& operator=(const LinkList<T>& source);
// destructor
~LinkList() { free(); }
// add / append / insert
void append(T dataIn);
void prepend(T dataIn);
// remove / Erase
void removeFirst();
bool remove(T item);
// clearAll
void clearAll() { free(); }
// isEmpty
//Find or contains
bool isEmpty() { return first == nullptr; }
// readFile
bool readFile(std::string fileName);
// writeFile
bool writeFile(std::string fileName);
void print();
int getSize();
Node<T>* at(int count);
Node<T>* getRandomItem();
private:
Node<T>* first;
Node<T>* last;
// alloc
Node<T>* alloc(T dataIn);
// free
void free();
Node<T>* find(T item);
};
#include "LinkList.tem"
#endif

LinkList.tem

template<typename T>
LinkList<T>::LinkList(const LinkList<T>& source) {
first = last = nullptr;
for (Node<T>* ptr = source.first; ptr != nullptr; ptr = ptr->next)
this->append(ptr->data);
}
template<typename T>
LinkList<T>& LinkList<T>::operator=(const LinkList<T>& source) {
if (this == &source)
return *this;
free();
first = last = nullptr;
for (Node<T>* ptr = source.first; ptr != nullptr; ptr = ptr->next)
this->append(ptr->data);
}
template<typename T>
void LinkList<T>::append(T dataIn) {
Node<T>* ptr = alloc(dataIn);
if (isEmpty())
first = last = ptr;
else {
last->next = ptr;
last = ptr;
}
}
template<typename T>
void LinkList<T>::prepend(T dataIn) {
Node<T>* ptr = alloc(dataIn);
if (isEmpty())
first = last = ptr;
else {
ptr->next = first;
first = ptr;
}
}
template <typename T>
bool LinkList<T>::remove(T item) {
if (isEmpty())
return false;
else if (item == first->data)
removeFirst();
else {
Node<T>* previous;
Node<T>* temp;
for (previous = first; previous != nullptr; previous->next) {
if (previous->next->data == item)
break;
}
temp = previous->next;
previous->next = temp->next;
delete temp;
}
return false;
}
template<typename T>
void LinkList<T>::removeFirst() {
Node<T>* tmp = first;
if (isEmpty())
return;
else if (!isEmpty() && first == last) {
delete tmp;
first = last = nullptr;
}
else {
first = tmp->next;
delete tmp;
}
}
template<typename T>
bool LinkList<T>::readFile(std::string fileName) {
std::ifstream inFS;
T data;
inFS.open(fileName);
if (!inFS.is_open()) {
std::cout << "Could not open " << fileName << std::endl;
return false;
}
while (!inFS.eof()) {
inFS >> data;
append(data);
}
inFS.close();
return true;
}
template<typename T>
bool LinkList<T>::writeFile(std::string fileName) {
std::ofstream outFS;
outFS.open(fileName);
if (!outFS.is_open()) {
std::cout << "Error opening " << fileName << std::endl;
return false;
}
for (Node<T>* ptr = first; ptr != nullptr; ptr = ptr->next)
outFS << ptr->data << std::endl;
outFS.close()
return true;
}
template<typename T>
void LinkList<T>::print() {
for (Node<T>* cursor = first; cursor != nullptr; cursor = cursor->next)
std::cout << cursor->data << std::endl;
}
template<typename T>
int LinkList<T>::getSize() {
int counter = 0;
if (first == nullptr)
return counter;
for (Node<T>* temp = first; temp != nullptr; temp = temp->next)
counter++;
return counter;
}
template<typename T>
Node<T>* LinkList<T>::at(int count) {
Node<T>* temp = first;
if (count > getSize())
return nullptr;
for (int i = 1; i < count; i++)
temp = temp->next;
return temp
}
template<typename T>
Node<T>* LinkList<T>::getRandomItem() {
srand(time(NULL));
return at(rand() % getSize() + 1)
}
template<typename T>
Node<T>* LinkList<T>::alloc(T dataIn) {
return new Node<T>(dataIn);
}
template<typename T>
void LinkList<T>::free() {
while (!isEmpty()) {
removeFirst();
}
}
template <typename T>
Node<T>* LinkList<T>::find(T item) {
if (isEmpty())
return nullptr;
for (Node<T>* tmp = first; tmp != nullptr; tmp = tmp->next)
if (tmp->data == item)
return tmp;
return nullptr;
}

为了完整性Node.h

#ifndef NODE_H
#define NODE_H
template <typename T>
class Node {
friend class LinkList;
public:
// Constructors
Node() : data(T()), next(nullptr) {}
Node(T dataIn) : data(dataIn), next(nullptr) {}
private:
// data members
T data;
Node<T>* next;
};
#endif

你在Node中的朋友声明不得不说LinkList是一个模板:

template <typename T>
class Node {
template <typename X> friend class LinkList; 

您的问题是需要将声明LinkList类模板转发到Node.h头文件中:

template <typename T>
class LinkList;

以及一些"打字错误

您的最终代码将是:

LinkList.h

#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include "Node.h"
template <typename T>
class LinkList { // This line is where I get the error
public:
LinkList() { first = last = nullptr; } // empty container
// value Semantic Functions
// copy constructor
LinkList(const LinkList<T>& source);
// assignment operator
LinkList<T>& operator=(const LinkList<T>& source);
// destructor
~LinkList() { free(); }
// add / append / insert
void append(T dataIn);
void prepend(T dataIn);
// remove / Erase
void removeFirst();
bool remove(T item);
// clearAll
void clearAll() { free(); }
// isEmpty
//Find or contains
bool isEmpty() { return first == nullptr; }
// readFile
bool readFile(std::string fileName);
// writeFile
bool writeFile(std::string fileName);
void print();
int getSize();
Node<T>* at(int count);
Node<T>* getRandomItem();
private:
Node<T>* first;
Node<T>* last;
// alloc
Node<T>* alloc(T dataIn);
// free
void free();
Node<T>* find(T item);
};
#include "LinkList.tem"
#endif

LinkList.tem

template<typename T>
LinkList<T>::LinkList(const LinkList<T>& source) {
first = last = nullptr;
for (Node<T>* ptr = source.first; ptr != nullptr; ptr = ptr->next)
this->append(ptr->data);
}
template<typename T>
LinkList<T>& LinkList<T>::operator=(const LinkList<T>& source) {
if (this == &source)
return *this;
free();
first = last = nullptr;
for (Node<T>* ptr = source.first; ptr != nullptr; ptr = ptr->next)
this->append(ptr->data);
}
template<typename T>
void LinkList<T>::append(T dataIn) {
Node<T>* ptr = alloc(dataIn);
if (isEmpty())
first = last = ptr;
else {
last->next = ptr;
last = ptr;
}
}
template<typename T>
void LinkList<T>::prepend(T dataIn) {
Node<T>* ptr = alloc(dataIn);
if (isEmpty())
first = last = ptr;
else {
ptr->next = first;
first = ptr;
}
}
template <typename T>
bool LinkList<T>::remove(T item) {
if (isEmpty())
return false;
else if (item == first->data)
removeFirst();
else {
Node<T>* previous;
Node<T>* temp;
for (previous = first; previous != nullptr; previous->next) {
if (previous->next->data == item)
break;
}
temp = previous->next;
previous->next = temp->next;
delete temp;
}
return false;
}
template<typename T>
void LinkList<T>::removeFirst() {
Node<T>* tmp = first;
if (isEmpty())
return;
else if (!isEmpty() && first == last) {
delete tmp;
first = last = nullptr;
}
else {
first = tmp->next;
delete tmp;
}
}
template<typename T>
bool LinkList<T>::readFile(std::string fileName) {
std::ifstream inFS;
T data;
inFS.open(fileName);
if (!inFS.is_open()) {
std::cout << "Could not open " << fileName << std::endl;
return false;
}
while (!inFS.eof()) {
inFS >> data;
append(data);
}
inFS.close();
return true;
}
template<typename T>
bool LinkList<T>::writeFile(std::string fileName) {
std::ofstream outFS;
outFS.open(fileName);
if (!outFS.is_open()) {
std::cout << "Error opening " << fileName << std::endl;
return false;
}
for (Node<T>* ptr = first; ptr != nullptr; ptr = ptr->next)
outFS << ptr->data << std::endl;
outFS.close();
return true;
}
template<typename T>
void LinkList<T>::print() {
for (Node<T>* cursor = first; cursor != nullptr; cursor = cursor->next)
std::cout << cursor->data << std::endl;
}
template<typename T>
int LinkList<T>::getSize() {
int counter = 0;
if (first == nullptr)
return counter;
for (Node<T>* temp = first; temp != nullptr; temp = temp->next)
counter++;
return counter;
}
template<typename T>
Node<T>* LinkList<T>::at(int count) {
Node<T>* temp = first;
if (count > getSize())
return nullptr;
for (int i = 1; i < count; i++)
temp = temp->next;
return temp;
}
template<typename T>
Node<T>* LinkList<T>::getRandomItem() {
srand(time(NULL));
return at(rand() % getSize() + 1);
}
template<typename T>
Node<T>* LinkList<T>::alloc(T dataIn) {
return new Node<T>(dataIn);
}
template<typename T>
void LinkList<T>::free() {
while (!isEmpty()) {
removeFirst();
}
}
template <typename T>
Node<T>* LinkList<T>::find(T item) {
if (isEmpty())
return nullptr;
for (Node<T>* tmp = first; tmp != nullptr; tmp = tmp->next)
if (tmp->data == item)
return tmp;
return nullptr;
}

节点.h

#ifndef NODE_H
#define NODE_H
template <typename T>
class LinkList;
template <typename T>
class Node {
friend class LinkList<T>;
public:
// Constructors
Node() : data(T()), next(nullptr) {}
Node(T dataIn) : data(dataIn), next(nullptr) {}
private:
// data members
T data;
Node<T>* next;
};
#endif

最新更新