带有专业模板声明的外部关键字
我正在使用一个代码库,该代码库在a.cpp
中具有以下声明:
template <int num_dim = 2>
int register_parameters();
extern template int register_parameters<2>(); // why is extern required here?
在b.cpp
中,我们定义
template <int num_dim = 2> int register_parameters() {
// define stuff
}
template int register_parameters<2>();
何时删除extern
关键字,我在编译时会收到以下错误,
error: explicit instantiation of ‘int register_parameters() [with int num_dim = 2]’ but no definition available [-fpermissive]
template int register_parameters<2>();
我想知道为什么在这种情况下需要extern
关键字?
I'm working with a code base that has the following declarations in a.cpp
:
template <int num_dim = 2>
int register_parameters();
extern template int register_parameters<2>(); // why is extern required here?
In b.cpp
, we define
template <int num_dim = 2> int register_parameters() {
// define stuff
}
template int register_parameters<2>();
When I remove the extern
keyword, I get the following error at compile time
error: explicit instantiation of ‘int register_parameters() [with int num_dim = 2]’ but no definition available [-fpermissive]
template int register_parameters<2>();
I am wondering why the extern
keyword is required in this case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些不是专业声明。明确的专业声明/定义使用
模板&lt;
而不是模板
和extern
无法在它们上使用。是显式实例声明。
是显式实例定义。
通常,当有一个模板的定义可用时,并且模板专业化(例如
register_parameters&lt; 2&gt;
都以一种需要定义为其存在的专业化的方式使用(例如,函数调用> code> register_parameters&lt; 2&gt;()
),编译器将隐式实例化将模板定义定义为特定专业化的定义(即函数的实际主体,即regission_parameters_parameters&lt; 2&gt; 2&gt;
用2
从模板定义中替换为ndims
)。为了使其能够做到这一点,通常需要在需要隐式实例化的点中定义模板在可用的标题文件中定义。显式实例定义指示编译器明确实例化该翻译单元中的模板专业化,并确保其他翻译单元也可以实例化(因此这些实际上不需要实例化/定义) 。
如果没有可用的模板定义,那么这当然可以行不通。因此,您的错误消息在问题结束时。
显式实例声明 指示编译器在程序中(else)中有一个相应的定义,并且模板专业化的隐式实例化在此翻译单元中不需要,不需要。无论如何,它无法在
a.cpp
中完成,因为它缺少模板的定义。因此,这两个共同确保程序中的模板专业化将完全实例化,来自翻译单元
b.cpp
具有显式实例定义,而不是更常见的方法在标题中定义模板,并在每个翻译单元中隐含实例化。These are not specialization declarations. Explicit specialization declarations/definitions use
template<>
instead oftemplate
andextern
can't be used on them like this.is an explicit instantiation declaration.
is an explicit instantiation definition.
Normally, when the definition of a template is available, and a template specialization like
register_parameters<2>
is used in a way that would require a definition of that specialization to exist (e.g. a function callregister_parameters<2>()
), the compiler would implicitly instantiate the template definition into the definition for the specific specialization (i.e. the actual body of the function thatregister_parameters<2>
refers to with2
substituted forndims
from the template definition). For it to be able to do that it is usually required that the template is defined in a header file available at the point requiring the implicit instantiation.The explicit instantiation definition instructs the compiler to explicitly instantiate the template specialization in this translation unit and guarantee that the instantiation is available to other translation units as well (so that these do not actually need an instantiation/definition).
If there is no definition for the template available, then this can of course not work. Hence your error message at the end of the question.
The explicit instantiation declaration instructs the compiler that there is a corresponding definition somewhere (else) in the program and that implicit instantiation of the template specialization should not be done and is not needed in this translation unit. It could not be done in
a.cpp
anyway though, since it lacks the definition of the template.So together these two make sure that there will be exactly one single instantiation of the template specialization in the program, coming from translation unit
b.cpp
with the explicit instantiation definition, instead of the more common approach of having the template be defined in a header and implicitly instantiated in each translation unit.