标准库非类型模板类是否显式实例化



当我们有一个带有非类型模板参数的模板化类(或函数(时,编译器是如何生成版本的?当然,它不会为N的每个可能值创建一个版本

假设std::array<T,N>这样的东西?

我正试图用size_t模板参数编写我自己的模板函数,并试图弄清楚是否/如何显式实例化我将使用的版本

(我把程序分成了不同的翻译单元(

我有一个类似的模板函数

template <size_t N>
std::bitset<N> f(std::bitset<N> A){}

我将声明放入头文件,将定义放入.cpp文件。它没有生成正确的版本。所以我试着像一样显式实例化它

template std::bitset<10> f<10>(std::bitset<10> A);

但我得到的错误是;错误:…的显式实例化。。。。但没有可用的定义";

无论标准库还是您都不需要显式实例化任何模板专用化,无论它是否具有非类型模板参数。

如果被实例化的实体的定义可用,则用户以需要专门化的定义的方式使用的模板的任何专门化将导致其自动被隐式实例化。通常应该始终满足该条件,因为标准做法是将模板实体的定义及其初始声明一起放入头文件中,以便在所有使用它们的翻译单元中都可以访问这些定义。

因此,对于翻译单元实际使用的所有类型T和值N对,std::array<T,N>将被隐式实例化。

唯一需要显式实例化的情况是,如果您打算将模板成员的定义分离到一个单独的翻译单元中,而不是头文件中,所有翻译单元都可以在头文件中隐式实例化这些定义。但是,只有首先知道模板参数的所有可能值,然后才需要显式实例化所有这些值,这对于大多数非类型模板参数来说是不可行的。

除此之外,通过避免在使用模板专业化的每个翻译单元中隐式实例化模板专业化,可以将显式实例化用作编译时间的优化。这只有在你知道会经常使用的专业领域才有意义。例如,一些标准库实现将其应用于std::string,即专用std::basic_string<char>。将其应用于例如std::array是没有意义的。

最新更新