在c ++中创建一个新的模板容器类型

时间:2011-03-04 02:54:57

标签: c++ templates stl containers

好的,所以我试图在c ++中实现模板化的循环双向链表。我遇到的问题是,当我尝试将类定义和函数分别分别放入.h和.cpp文件时,编译器不断向我吐出有关没有模板参数的错误。

这是头文件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

4 个答案:

答案 0 :(得分:4)

不幸的是,由于C ++编译过程的工作方式,它们需要位于同一个文件中(除此之外还有其他解决方法,但这是最常见的解决方法)。有关详细信息,请参阅http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

答案 1 :(得分:1)

您无法将模板化功能拆分为.cpp文件和标题。当编写和编译模板类时,它实际上并不是在正常意义上“编译”的。相反,只有在为其指定模板参数时才会编译它。因此,每次在代码中生成以前未完成的Foo<Bar>声明时,实际上都需要编译器生成一个全新的类。如果不知道如何实现整个新类,它就无法编译新类。这就是你的编译器吐出你看到的错误的原因。

更具描述性。我们假设我创建了一个名为“bleah.h”的文件

template<typename T>
struct Foo{ T value; }

现在我在“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>

由于我在这里有标题,我需要标题中的所有信息来编译“Foo”的不同模板版本。

答案 2 :(得分:0)

尝试添加&lt; T&gt;在cpp

中定义函数时的类名

e.g。

template<class T> void myclass<T>::func_name() {}

正如其他海报所指出的那样,你应该把放在.cpp中的东西放在.inl文件中,然后在.h文件的末尾做#include“myfile.inl”,避免使用.cpp文件作为模板

答案 3 :(得分:0)

您无法将实现与模板类的声明分开,就像使用常规类一样。你可以做到这一点,但它有点“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