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

标签 c++ templates undefined-reference c++-faq

引自 The C++ standard library: a tutorial and handbook :

The only portable way of using templates at the moment is to implement them in header files by using inline functions.



为什么是这样?

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

最佳答案

警告:没有必要将实现放在头文件中,请参阅本答案末尾的替代解决方案。

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

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

因此,编译器需要访问方法的实现,以使用模板参数(在本例中为 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
}

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

替代方案

另一种解决方案是保持实现分离,并显式实例化您需要的所有模板实例:

foo.h
// no implementation
template <typename T> struct Foo { ... };

文件
// 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++ Super-FAQ on this subject .

关于c++ - 为什么模板只能在头文件中实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69243333/

相关文章:

c++ - 如何向模板类公开统一接口(interface)?

c++ - 如何判断模板类型是否是模板类的实例?

c++ - 使用带有 CMake 和 Conan 的外部库的 undefined reference

c++ - 出现在函数表达式中的变量是否通过引用获取参数但通过值 odr-used 返回?

c++ - 基础C++递归程序题

c++ - 类模板特化中的成员变量别名

c++ - 在 *.cpp 而不是 *.h 中定义函数时出现 undefined reference 错误

linux - 对符号 'pthread_key_delete@@GLIBC_2.2.5 的 undefined reference

c++ - getaddrinfo 失败,错误为 : Servname not supported for ai_socktype in C++

C++将一个数组拆分为2个单独的数组