Warm tip: This article is reproduced from serverfault.com, please click

c++-为什么只能在头文件中实现模板?

(c++ - Why can templates only be implemented in the header file?)

发布于 2009-01-30 10:06:50

引用来自C ++标准库:教程和手册

目前使用模板的唯一可移植方法是通过使用内联函数在头文件中实现模板。

为什么是这样?

(澄清:头文件不是唯一的可移植解决方案。但是它们是最方便的可移植解决方案。)

Questioner
MainID
Viewed
11
148k 2020-03-09 22:52:26

警告:这是没有必要把落实在头文件中,看到这个答案的末尾替代解决方案。

无论如何,你的代码失败的原因是,在实例化模板时,编译器会使用给定的模板参数创建一个新类。例如:

template<typename T>
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f; 

阅读此行时,编译器将创建一个新类(我们称之为FooInt),其等效于以下内容:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

因此,编译器需要访问方法的实现,以使用template参数实例化它们(在这种情况下为int)。如果这些实现不在头文件中,则将无法访问它们,因此编译器将无法实例化模板。

一种常见的解决方案是将模板声明写入头文件中,然后在实现文件中实现该类(例如.tpp),并在头末尾包含该实现文件。

oo

template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

Foo.tpp

template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}

这样,实现仍与声明分开,但编译器可以访问。

替代解决方案

另一个解决方案是使实现分离,并显式实例化你需要的所有模板实例:

oo

// 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

如果我的解释不够清楚,你可以查看有关此主题C ++超级常见问题解答