Создание нового типа шаблона контейнера в C ++ - PullRequest
3 голосов
/ 04 марта 2011

Хорошо, поэтому я пытаюсь реализовать шаблонный круговой двусвязный список в 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 ]

4 голосов
/ 04 марта 2011

К сожалению, из-за того, как работает процесс компиляции C ++, они должны находиться в одном и том же файле (кроме этого есть и другие обходные пути, но это наиболее распространенный). Подробнее см. http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12.

1 голос
/ 04 марта 2011

Нельзя разделить шаблонные функции на файл .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".

0 голосов
/ 04 марта 2011

Вы не можете отделить реализацию от объявления с помощью шаблонных классов, как с обычными классами. Вы можете сделать это, но это немного "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
0 голосов
/ 04 марта 2011

попробуйте добавить к имени класса при определении функции в cpp

, например

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

Как указали другие авторы, вы должны поместить материал, который вы положили в .cpp, в файл .inl и сделать #include "myfile.inl" в конце файла .h, и избегать использования файлов .cpp для шаблонов. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...