Reputation: 31
Ok, so I am trying to implement a templated circular doubly linked list in c++. The problem I am running into is that when I try to separate the class definition and the functions into .h and .cpp files respectively, the complier keeps spitting out errors at me about not having the template parameters.
Here is the header file, cdl_list.h
#ifndef CDL_LIST_H
#define CDL_LIST_H
#include <iostream>
using namespace std;
template <typename T>
class cdl_list {
public:
cdl_list(){
first = last = current = NULL;}; // constructor, "current" = "null"
~cdl_list(); // deconstructor
void insertFromFront (T &); // inserts an element of type T in the front properly
void insertFromBack (T &); // inserts an element of type T in the back properly
void deleteFront(); // removes the first element in the list, updating relevant pointers
void deleteBack(); // removes the last element in the list, updating relevant pointers
void reset(); // makes the "current" pointer the front element
void next(); // makes the "current" pointer the next node neighbor
T currentValue(); // return the data in the node that "current" refers to
void deleteCurrent(); // delete the node that the current pointer refers to; current = old -> next
bool isEmpty(); // returns true if and only if the list is empty
void print(); // displays the current data in the linked list
private:
struct listNode* first;
struct listNode* last;
struct listNode* current;
protected:
struct listNode {
listNode* prev; // "previous" pointer
T data; // data in the node
listNode* next; // "next" pointer
};
};
#include "cdl_list.h"
#include <iostream>
using namespace std;
//And here is the .cpp file, what I have so far, because I can't even get just this one function to compile
template < typename T > void cdl_list::insertFromFront(const T &frontInsert) {
listNode *oldFirst;
oldFirst = (listNode *) malloc(sizeof(listNode));
oldFirst = first;
oldFirst -> prev = frontInsert;
while(current -> next != first)
current = current -> next;
frontInsert -> prev = current;
current -> next = frontInsert;
first = frontInsert;
}
#endif
Upvotes: 3
Views: 369
Reputation: 25612
You can't really separate implementation from declaration with template classes like you can with regular classes. You can do this, but it's a bit "hacky:"
// Template.h
#ifndef TEMPLATE_H_INCLUDED
#define TEMPLATE_H_INCLUDED
template <typename ClassDatatype>
class MyTemplateClass
{
template <typename MethodDatatype>
void MyMethod(MethodDatatype Argument);
}
#include "Template.cpp"
#endif
// Template.cpp
#ifndef TEMPLATE_CPP_INCLUDED
#define TEMPLATE_CPP_INCLUDED
#include "Template.h"
template <typename ClassDatatype>
template <typename MethodDatatype>
void MyTemplateClass<ClassDatatype>::MyMethod(MethodDatatype Argument)
{
// Implementation goes here.
}
#endif
Upvotes: 0
Reputation: 1020
try adding a <T> to the classname when defining the function in cpp
e.g.
template<class T> void myclass<T>::func_name() {}
as the other posters pointed put you should put the stuff you put in .cpp in a .inl file and do #include "myfile.inl" right at the end of the .h file and avoid using .cpp files for templates.
Upvotes: 0
Reputation: 35990
You can not split the templated functions into a .cpp file and a header. When a template class is written and compiled it is not actually "compiled" in the normal sense. Instead, it is only compiled when you assign it a template parameter. So each time you make a previously unmade declaration of Foo<Bar>
within your code you are actually requiring the compiler to generate a whole new class. Without knowledge of how to implement the entirety of that new class, it can not compile the new class. That's why your compiler is spitting out the errors you are seeing.
To be more descriptive. Let's assume that I create a file called "bleah.h"
template<typename T>
struct Foo{ T value; }
and now I have this in "Yuck.h":
#include "bleah.h"
Foo<int> something; //compiler stops here and compiles a new class for Foo<int>
Foo<int> another; //compiler doesn't need to generate a new Foo<int>, already done
Foo<double> oh; //compiler needs to make a new class Foo<double>
Since I have the header here I need all that information in the header to compile the different templated versions of "Foo."
Upvotes: 1
Reputation: 4887
Unfortunately, because of the way the C++ compilation process works, they need to be in the same file (there are other workarounds besides this, but this is the most common one). See http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12 for more details.
Upvotes: 4