【问题标题】:Defining methods of class with template parameters使用模板参数定义类的方法
【发布时间】:2011-08-14 17:48:54
【问题描述】:

文件 main2.cpp:

#include "poly2.h"

int main(){
 Poly<int> cze;
 return 0;
}

文件 poly2.h:

template <class T>
class Poly {
public:
 Poly();
};

文件 poly2.cpp:

#include "poly2.h"

template<class T>
Poly<T>::Poly() {
}

编译时出错:

src$ g++ poly2.cpp main2.cpp -o poly
/tmp/ccXvKH3H.o: In function `main':
main2.cpp:(.text+0x11): undefined reference to `Poly<int>::Poly()'
collect2: ld returned 1 exit status

我正在尝试编译上面的代码,但是编译过程中出现了错误。编译带模板参数的构造函数应该解决什么问题?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    完整的模板代码必须出现在一个文件中。您不能像使用普通类那样在多个文件之间分离接口和实现。为了解决这个问题,许多人将类定义写在头文件中,将实现写在另一个文件中,并将实现包含在头文件的底部。例如:

    Blah.h:

    #ifndef BLAH_H
    #define BLAH_H
    
    template<typename T>
    class Blah {
        void something();
    };
    
    #include "Blah.template"
    
    #endif
    

    废话模板:

    template<typename T>
    Blah<T>::something() { }
    

    预处理器会将Blah.template 的内容复制粘贴到Blah.h 标头中,当编译器看到它时,所有内容都会在一个文件中,每个人都很高兴。

    【讨论】:

      【解决方案2】:

      如果您在 C++ 中使用模板,则所有使用模板的函数实现都需要在您的头文件中。或者您的编译器找不到类型的正确(或任何)版本。

      详情请参阅this问题。

      【讨论】:

        【解决方案3】:

        如何定义我的模板类这个古老的问题。模板实际上不是代码,它是您以后用来定义代码的模板。因此,有两种可能的解决方案,如果您知道只有某些类型的 Poly 是您要使用的,您可以在 .cpp 文件中定义它们。

        #include "poly2.h"
        Poly<int>;
        
        template<class T>
        Poly<T>::Poly() {
        }
        

        或者您可以将所有模板定义和声明放在头文件中。我喜欢做的是创建一个单独的 .hpp 文件并将定义放在那里。所以我会这样做:

        poly2.h

        template <class T>
        class Poly {
        public:
         Poly();
        };
        #include "poly2-impl.hpp"
        

        poly2-impl.hpp

        template<class T>
        Poly<T>::Poly() {
        }
        

        关于模板的事情是,您可以将头文件包含在多个翻译文件中,而不会出现先前定义的错误。

        更多信息请看这里:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

        【讨论】:

          【解决方案4】:

          通常,编译一个源文件只需要一堆函数声明,你可以稍后链接到定义中。

          不幸的是,当模板混入其中时,事情并不是那么简单。因为模板在使用时必须实例化,所以它们的定义在使用时必须是可见的。 main2.cpp 看不到Poly&lt;int&gt;::Poly() 的定义,所以没有实例化这个函数。因此它从目标文件中丢失并且不可链接。

          您应该在头文件中编写函数模板,以便它们在您使用它们的所有翻译单元中可用。这并不理想,但如果没有 export(或执行显式实例化),您将无能为力。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多