It is not necessary to put the implementation in the header file, see the alternative solution at the end of this answer.
(这是没有必要把落实在头文件中,看到这个答案的末尾替代解决方案。)
Anyway, the reason your code is failing is that, when instantiating a template, the compiler creates a new class with the given template argument.
(无论如何,您的代码失败的原因是,在实例化模板时,编译器会使用给定的template参数创建一个新类。)
For example: (例如:)
template<typename T>
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};
// somewhere in a .cpp
Foo<int> f;
When reading this line, the compiler will create a new class (let's call it FooInt
), which is equivalent to the following:
(阅读此行时,编译器将创建一个新类(我们将其FooInt
),其等效于以下内容:)
struct FooInt
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}
Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int
).
(因此,编译器需要访问方法的实现,以使用模板参数(在本例中为int
)实例化它们。)
If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template. (如果这些实现不在头文件中,则将无法访问它们,因此编译器将无法实例化模板。)
A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.
(常见的解决方案是将模板声明写在头文件中,然后在实现文件(例如.tpp)中实现该类,并在头末尾包含此实现文件。)
// Foo.h
template <typename T>
struct Foo
{
void doSomething(T param);
};
#include "Foo.tpp"
// Foo.tpp
template <typename T>
void Foo<T>::doSomething(T param)
{
//implementation
}
This way, implementation is still separated from declaration, but is accessible to the compiler.
(这样,实现仍与声明分开,但编译器可以访问。)
Alternative solution (替代解决方案)
Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you'll need:
(另一个解决方案是使实现分离,并显式实例化所需的所有模板实例:)
// Foo.h
// 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
If my explanation isn't clear enough, you can have a look at the C++ Super-FAQ on this subject .
(如果我的解释不够清楚,您可以阅读有关此主题的C ++ Super-FAQ 。)