我正在尝试创建一个Templated类来保存不同的对象,以便了解一些对我来说不熟悉的自写数据结构和ptrs。 我被困在这一点上:
template <class T> class Linked_List
{
struct Node
{
T data;
Node* prev;
Node* next;
Node(T d, Node* p, Node* n) : data(d),
prev(p), next(n) {}
};
public:
Linked_List();
~Linked_List();
void push_back(T data);
void push_front(T data);
void insertAt(T data, int pos);
T pop_back();
T pop_front();
int size();
bool empty();
private:
Node* tail;
Node* head;
};
我收到此错误:'Linked_List<T>::Node::data' uses undefined class 'T'
。 (使用VS2013)
我做错了什么?
谢谢
更新
#include "Linked_List.h"
template<class T> Linked_List<T>::Linked_List()
{
head = 0;
tail = 0;
}
template<class T> Linked_List<T>::~Linked_List()
{
{
while (head)
{
Node* temp(head); //pointer to head
head = head->next; // go to next
delete temp; //delete the pointer
}
}
}
template <class T>
void Linked_List<T>::push_back(T data)
{
//create the new Node
tail = new Node(data, tail, NULL);
if (tail->prev) //add to tail
tail->prev->next = tail;
if (empty()) // if empty its also the head
head = tail;
}
template <class T>
void Linked_List<T>::push_front(T data)
{
head = new Node(data, 0, tail);
if (head->next)
head->next->prev = head;
if (empty())
tail = head;
}
template <class T>
bool Linked_List<T>::empty()
{
return (!head || !tail);
}
template <class T>
T Linked_List<T>::pop_back()
{
if (empty())
throw("Linked_list is empty!");
//pointer to the element we want to have
Node* temp(tail);
//set the tail to prev
tail = tail->prev;
//get the data
T data = temp->data;
//the prev does not have a next now
if (tail)
tail->next = 0;
else
head = 0;
//delete the node which held our data
delete temp;
//return the data
return data;
}
template <class T>
T Linked_List<T>::pop_front()
{
if (empty())
throw("Linked_list is empty!");
//pointer to the element we want to have
Node* temp(head);
//set the tail to prev
head = head->next;
//get the data
T data = temp->data;
//the prev does not have a next now
if (head)
head->prev = 0;
else
tail = 0;
//delete the node which held our data
delete temp;
//return the data
return data;
}
新的stacktrace,如果我试图像这样使用它
int main(){
Linked_List<int> list;
for (int i = 0; i < 20; i++)
{
list.push_back(i);
}
for (int j = 0; j < 20; j++)
{
cout << list.pop_back() << endl;
}
}
错误:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Linked_List<int>::Linked_List<int>(void)" (??0?$Linked_List@H@@QAE@XZ) referenced in function _main C:\Users\...\Documents\Visual Studio 2013\Projects\Double_Linked_List\Double_Linked_List\main.obj Double_Linked_List
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Linked_List<int>::~Linked_List<int>(void)" (??1?$Linked_List@H@@QAE@XZ) referenced in function _main C:\Users\...\Documents\Visual Studio 2013\Projects\Double_Linked_List\Double_Linked_List\main.obj Double_Linked_List
Error 3 error LNK2019: unresolved external symbol "public: void __thiscall Linked_List<int>::push_back(int)" (?push_back@?$Linked_List@H@@QAEXH@Z) referenced in function _main C:\Users\...\Documents\Visual Studio 2013\Projects\Double_Linked_List\Double_Linked_List\main.obj Double_Linked_List
Error 4 error LNK2019: unresolved external symbol "public: int __thiscall Linked_List<int>::pop_back(void)" (?pop_back@?$Linked_List@H@@QAEHXZ) referenced in function _main C:\Users\...\Documents\Visual Studio 2013\Projects\Double_Linked_List\Double_Linked_List\main.obj Double_Linked_List
Error 5 1 error LNK1120: 4 unresolved externals C:\Users\...\Documents\Visual Studio 2013\Projects\Double_Linked_List\Debug\Double_Linked_List.exe 1 Double_Linked_List
答案 0 :(得分:3)
链接器非常清楚:您缺少这些方法的定义。编译器没有抱怨,因为它看到了Linked_List类的声明,但在处理模板时,这还不够。
为了使模板实例化成功,所有模板定义都需要可见。因为,您在cpp文件中实现了模板类的方法(人们通常在头文件或impl文件中执行),您需要包含实例化模板的文件。在您的具体示例中,在main.cpp中:
#include <iostream>
#include "Linked_List.cpp" // !!!
int main(){
Linked_List<int> list;
for (int i = 0; i < 20; i++)
{
list.push_back(i);
}
for (int j = 0; j < 20; j++)
{
std::cout << list.pop_back() << std::endl;
}
}
您可以在源文件中明确地执行此操作,而不是包含植入文件,并让编译器隐式实例化模板。在这种情况下,请在Linked_List.cpp:
的末尾添加此行template class Linked_List<int>;
但在这种情况下,您将无法使用不同的模板参数(int除外)创建对象。
第三个选项是第一个选项的变体。将源文件包含在标题的末尾。
标题
// header.hpp
#ifndef HEADER_HPP
#define HEADER_HPP
template< typename T >
struct A
{
void foo();
};
#include "source.impl"
#endif
来源
// source.impl
#include "header.hpp"
template< typename T >
void A::foo()
{
}
主要
// main.cpp
#include "header.hpp"
int main()
{
A<int> a;
a.foo();
}
答案 1 :(得分:0)
我猜你已经将模板类的定义和方法的实现放在两个文件中,就像你对普通的非模板类所做的那样;并且您只需在main.cpp中包含定义链接列表的头文件。
请参阅此主题,了解您无法执行此操作的原因