David
David

Reputation: 31

Creation of a new template container type in c++

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

Answers (4)

Maxpm
Maxpm

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

mohaps
mohaps

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

wheaties
wheaties

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

user470379
user470379

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

Related Questions