简体   繁体   English

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

[英]Are standard library non-type template classes explicitly instantiated?

When we have a templated class (or function) that has a non-type template parameter, how are the versions generated by the compiler?当我们有一个具有非类型模板参数的模板化 class(或函数)时,编译器如何生成版本? Surely it doesn't create a version for every possible value of N当然,它不会为N的每个可能值创建一个版本

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

I am trying to write my own templated function with a size_t template parameter, and I am trying to figure out whether/how I need to explicitly instantiate versions I will use我正在尝试使用 size_t 模板参数编写自己的模板化 function,并且我试图弄清楚是否/如何需要显式实例化我将使用的版本

(I have split the program across different translation units) (我已将程序拆分为不同的翻译单元)

I have a templated function which is something like我有一个模板化的 function 类似于

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

I put the declaration into a header file and definition into a.cpp file.我将声明放入 header 文件并将定义放入 a.cpp 文件。 It doesn't generate the correct version.它不会生成正确的版本。 So I tried to explicitly instantiate it like所以我试图明确地实例化它

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

but I get the error that "error: explicit instantiation of.... but no definition available"但我收到“错误:显式实例化....但没有可用定义”的错误

Neither the standard library nor you need to explicitly instantiate any template specialization, whether it has non-type template parameters or not.标准库和您都不需要显式实例化任何模板特化,无论它是否具有非类型模板参数。

Any specialization of the template which is used by the user in a way that requires a definition for the specialization to exist will cause it to automatically be implicitly instantiated if a definition for the entity which is instantiated is available.如果被实例化的实体的定义可用,则用户以需要存在专门化定义的方式使用的模板的任何专门化将导致它自动被隐式实例化。 The condition should normally always be fulfilled since it is standard practice to place definitions of templated entities into the header file along with their initial declaration, so that they are accessible in all translation units using them.通常应始终满足该条件,因为将模板化实体的定义连同它们的初始声明一起放入 header 文件是标准做法,以便在使用它们的所有翻译单元中都可以访问它们。

So std::array<T,N> will be implicitly instantiated for all pairs of types T and values N which are actually used by the translation unit.因此std::array<T,N>将为翻译单元实际使用的所有类型T和值N对隐式实例化。

The only situation where explicit instantiation is required is if you intent to separate the definitions of template members into a single translation unit instead of the header file where they would be available for all translation units to implicitly instantiate.需要显式实例化的唯一情况是,如果您打算将模板成员的定义分离到单个翻译单元而不是 header 文件中,在该文件中它们可用于所有翻译单元以隐式实例化。 But you can only do that in the first place if you know all possible values for the template parameters, and you would then need to explicitly instantiate all of them, which for most non-type template parameters is not feasible.但是,如果您知道模板参数的所有可能值,则只能首先执行此操作,然后您需要显式实例化所有这些值,这对于大多数非类型模板参数是不可行的。

Aside from that explicit instantiation may be used as an optimization of compilation time by avoiding implicitly instantiating template specializations in every translation unit where they are used.除了显式实例化之外,还可以通过避免在每个使用它们的翻译单元中隐式实例化模板特化来优化编译时间。 That makes sense only for specializations which you know will be often used.这仅对您知道将经常使用的专业化有意义。 For example some standard library implementations apply it to std::string , which is the specialization std::basic_string<char> .例如,一些标准库实现将其应用于std::string ,这是专门化std::basic_string<char> It doesn't really make sense to apply it to eg std::array .将它应用于例如std::array并没有任何意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM