为什么模板只能在头文件中实现?
警告:没有必要将实现放在头文件中,请参阅此答案末尾的替代解决方案。
无论如何,您的代码失败的原因是,在实例化模板时,编译器会使用给定的模板参数创建一个新类。例如:
template<typename T> struct Foo { T bar; void doSomething(T param) {/* do stuff using T */} }; // somewhere in a .cpp Foo<int> f;
读到这一行时,编译器会新建一个类(我们称之为FooInt),相当于如下:
FooInt
struct FooInt { int bar; void doSomething(int param) {/* do stuff using int */} }
因此,编译器需要访问方法的实现,以使用模板参数(在本例中int)实例化它们。如果这些实现不在标头中,它们将无法访问,因此编译器将无法实例化模板。
int
一个常见的解决方案是在头文件中编写模板声明,然后在实现文件(例如 .tpp)中实现该类,并将该实现文件包含在头文件的末尾。
Foo.h
template <typename T> struct Foo { void doSomething(T param); }; #include "Foo.tpp"
文件.tpp
template <typename T> void Foo<T>::doSomething(T param) { //implementation }
这样,实现仍然与声明分离,但编译器可以访问。
另一种解决方案是保持实现分离,并显式实例化您需要的所有模板实例:
// no implementation template <typename T> struct Foo { ... };
Foo.cpp
// implementation of Foo's methods // explicit instantiations template class Foo<int>; template class Foo<float>; // You will only be able to use Foo with int or float