模板的显式实例化

bad*_*lms 2 c++ templates

该线程确实很有帮助,但我仍然对这个过程有疑问,但似乎没有得到解答。

我必须在多大程度上显式实例化模板?例如,如果在我的定义文件中,我在每个函数、友元类、运算符重载等上使用模板,我是否必须在模板实例化文件中实例化每个模板(我正在使用的当前方法)?

根据我的反复试验,答案似乎是否定的,一个简单的方法

template class Class<type>;
Run Code Online (Sandbox Code Playgroud)

将为班级的所有成员工作。然而,我已经阅读了其他建议的代码,并且将不胜感激具体的答案。

vso*_*tco 5

一般来说,您不需要显式实例化模板,只需在头文件中定义它并包含该头文件即可。然而,显式模板实例化的一个常见应用是当您想要“隐藏”模板的定义时。想象一下以下情况,为了简单起见,我们隐藏了模板函数的实现:

头文件.h

template<class X> void f(); // declaration
Run Code Online (Sandbox Code Playgroud)

头文件.cpp

#include "header.h"

template<class X> void f(){ /* definition */ }
template void f<int>();    // explicit instantiation for int, force the compiler to generate code
template void f<double>(); // explicit instantiation for double, same
Run Code Online (Sandbox Code Playgroud)

主程序

#include "header.h"

int main()
{
    f<int>(); // OK
    f<double>(); // also OK
    f<char>(); // linker error
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该函数f是在header.cpp文件中定义的(而不是header.h)中,因此对用户隐藏了实现。由于int和的显式实例化,编译器在编译时double将能够找到f<int>()和的代码。但是,当尝试查找编译时的代码时,我们收到链接器错误。这是因为编译是独立完成的,当编译器编译 时,编译器只生成和的代码,并不知道我们会调用,所以它不会生成 的代码。f<double>();main.cppf<char>();main.cppheader.cppf<int>f<double>f<char>f<char>

唯一的问题是,为了利用这种代码隐藏,我们必须为要使用该函数的所有类型显式实例化该函数,否则会出现链接器错误。