使用模板参数定义类的方法

时间:2011-08-14 17:48:54

标签: c++ templates

文件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

我正在尝试编译上面的代码,但在编译期间有错误。使用模板参数编译构造函数应该修复什么?

4 个答案:

答案 0 :(得分:4)

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

Blah.h:

#ifndef BLAH_H
#define BLAH_H

template<typename T>
class Blah {
    void something();
};

#include "Blah.template"

#endif

Blah.template:

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

预处理器将等同于Blah.template内容的Blah.h内容的复制粘贴,编译器看到它时所有内容都在一个文件中,并且每个人都是高兴。

答案 1 :(得分:1)

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

有关详细信息,请参阅this个问题。

答案 2 :(得分:1)

如何定义模板类的古老问题。模板实际上不是代码,它是您稍后用于定义代码的模板。因此,有两种可能的解决方案,如果您知道将要使用的某些类型的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"

聚2- impl.hpp

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

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

有关详细信息,请参阅此处:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

答案 3 :(得分:0)

通常,编译源文件所需的只是一堆函数声明,稍后可以在定义中进行链接。

不幸的是,当模板进入组合时,它并不那么简单。由于模板在使用时必须实例化,因此在使用时它们的定义必须是可见的。 main2.cpp无法看到Poly<int>::Poly()的定义,因此未对此函数进行实例化。因此它从目标文件中丢失而且不可链接。

您应该在头文件中编写功能模板,以便它们可以在您使用它们的所有翻译单元中使用。它并不理想,但没有export(或执行显式实例化),你可以做很多事情。

相关问题