C++ 显式实例化同时仍允许其他类型的隐式实例化?

Chr*_*nam 1 c++ templates

我有一个基本上都是模板化的项目。然而,我知道一个事实是,99% 的用户只需要可能实例化的特定子集。

例如,我有一个Camera类,99% 的用户只会将其实例化为以下类型之一:

Camera<float,Mono>
Camera<float,RGB>
Camera<double,Mono>
Camera<double,RGB>
Run Code Online (Sandbox Code Playgroud)

但是,有一些小众用户需要使用以下内容:

Camera<float, Spectrum<N>>
Run Code Online (Sandbox Code Playgroud)

其中N仅针对用户的特定程序才知道。

过去,我使用显式实例化,我知道我想要的实例化的特定子集,这极大地加快了编译时间,并允许我将实现与头文件分开。(我非常喜欢仅声明头文件以提高可读性)。

然而在这里,因为我想要这种灵活性,所以我将其保留为仅包含标题的模板。

是否可以为已知情况提供显式实例化以帮助加快编译时间,同时仍然允许用户在绝对需要时指定自己的隐式实例化?

我正在考虑的另一种选择是完全显式实例化(将所有定义移至文件中.cpp),然后显式实例化:

Camera<float, Spectrum<SPECTRAL_BIN_COUNT>
Run Code Online (Sandbox Code Playgroud)

可以SPECTRAL_BIN_COUNT通过 a 设置#define。(如果没有设置,将简单地默认为某个值)。

我对后者的担忧是,将来我可能需要一些额外的灵活性,因此希望模板实例化能够完全灵活。

use*_*522 5

没有什么特别需要你照顾的。您只需像往常一样定义标头中的所有内容并包含显式实例化的声明。然后在您的文件中.cpp为这些实例化提供定义。然后,所有用户都拥有可用于隐式实例化的所有定义,但不会隐式实例化显式实例化的专业化。

在类模板定义(和成员定义)之后的标头中添加显式实例化声明:

extern template Camera<float,Mono>;
extern template Camera<float,RGB>;
extern template Camera<double,Mono>;
extern template Camera<double,RGB>;
Run Code Online (Sandbox Code Playgroud)

并在您的库中.cpp,包含标头后,添加显式实例化定义:

template Camera<float,Mono>;
template Camera<float,RGB>;
template Camera<double,Mono>;
template Camera<double,RGB>;
Run Code Online (Sandbox Code Playgroud)

还要确保您没有将成员函数声明为inline,即在类外定义它们并且不添加inline说明符。否则,显式实例化声明将不会阻止隐式实例化。