在另一个标题中强制模板实例化
Posted
技术标签:
【中文标题】在另一个标题中强制模板实例化【英文标题】:Force template instantiation in another header 【发布时间】:2015-08-25 16:56:08 【问题描述】:我有一个模板化的“收藏”类。我不想在每个源文件中重新编译代码。但是这个集合应该与模板类定义中未定义的 DataTypes (class SpecialDataMember : DataMember
) 一起使用。
这就是为什么我不能在模板源文件中强制实例化(通过将定义移动到源文件并添加template LinkCollection<DataMember>;
),因为模板的定义必须可以在其他源文件中访问(“SpecialDataMember.cpp
” )。
是否可以让“SpecialDataMember.o
”保存LinkCollection<SpecialDataMember>
的代码。 SpecialDataMember.h
的每个包含者都应该知道我将 LinkCollection<SpecialDataMember>
留给了链接器。
我看到两个选项,但我不知道它们是否有效:
-
制作两个模板标头(带有标头保护),一个带有定义,一个没有。
SpecialDataMember.h
// ..
include "LinkCollection.h"
// ..
SpecialDataMember.cpp
// ..
include "LinkCollectionImpl.h"
// ..
include "SpecialDataMember.h"
// ..
template LinkCollection<SpecialDataMember>;
“SpecialDataMember.h
”的所有包含器都不知道模板的定义,因此它们会让链接器完成他的工作。链接器将在SpecialDataMember.o
中找到LinkCollection<SpecialDataMember>
的实例化。那是对的吗?
但我必须维护两个头文件。有没有更好的方法来获得这种效果?
-
使用模板派生类
如果我在“SpecialDataMember
”头文件和源文件中创建一个特殊的class SpecialDataMemberLinkCollection : LinkCollection<SpecialDataMemberLink>
,我可以改为引用这个特殊的类,这样编译器就知道该类和基类模板的实例化并留下工作到链接器。这会按预期工作吗?
【问题讨论】:
为什么以及如何获得想要的效果? 我读了“重复”,问题不同,答案没有帮助。我正在使用第一个选项的答案中描述的技术。不同之处在于我在另一个源文件中强制实例化。 【参考方案1】:是否可以让“SpecialDataMember.o”保存
LinkCollection<SpecialDataMember>
的代码。SpecialDataMember.h
的每个包含者都应该知道我将LinkCollection<SpecialDataMember>
留给了链接器。
简单,简单地说:
extern template class LinkCollection<SpecialDataMember>;
在标头中,它告诉编译器不要实例化该模板并将其留给另一个文件。
然后在一个SpecialDataMember.cpp
文件中提供该实例化:
template class LinkCollection<SpecialDataMember>;
【讨论】:
如果在标题中定义了extern template LinkCollection<SpecialDataMember>;
,template LinkCollection<SpecialDataMember>;
会起作用吗?
是的。就像声明一个函数然后定义它一样工作正常。 extern template
是一个显式的实例化声明,它说“在程序的某个地方会有一个显式的实例化定义”,但它并没有说该定义不能在同一个文件中稍后出现。
@PiotrSkotnicki,不,我只是从问题中复制和粘贴,它丢失了:) 现在已修复,谢谢以上是关于在另一个标题中强制模板实例化的主要内容,如果未能解决你的问题,请参考以下文章