【问题标题】:Creation of a new template container type in c++在 C++ 中创建新的模板容器类型
【发布时间】:2011-03-04 02:54:56
【问题描述】:

好的,所以我正在尝试在 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

【问题讨论】:

    标签: c++ templates stl containers


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您不能将模板化函数拆分为 .cpp 文件和标头。当一个模板类被编写和编译时,它实际上并不是正常意义上的“编译”。相反,它仅在您为其分配模板参数时才被编译。因此,每次您在代码中对 Foo&lt;Bar&gt; 进行先前未声明的声明时,实际上都需要编译器生成一个全新的类。如果不知道如何实现整个新类,就无法编译新类。这就是为什么你的编译器会吐出你看到的错误。

      为了更具描述性。假设我创建了一个名为“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”的不同模板版本。

      【讨论】:

        【解决方案3】:

        在 cpp 中定义函数时,尝试在类名中添加

        例如

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

        正如其他海报指出的那样,您应该将放入 .cpp 的内容放入 .inl 文件中,并在 .h 文件的末尾执行 #include "myfile.inl" 并避免将 .cpp 文件用于模板.

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-10
            • 2021-12-28
            • 1970-01-01
            相关资源
            最近更新 更多