在另一个标题中强制模板实例化

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&lt;SpecialDataMember&gt; 的实例化。那是对的吗? 但我必须维护两个头文件。有没有更好的方法来获得这种效果?

    使用模板派生类

如果我在“SpecialDataMember”头文件和源文件中创建一个特殊的class SpecialDataMemberLinkCollection : LinkCollection&lt;SpecialDataMemberLink&gt;,我可以改为引用这个特殊的类,这样编译器就知道该类和基类模板的实例化并留下工作到链接器。这会按预期工作吗?

【问题讨论】:

为什么以及如何获得想要的效果? 我读了“重复”,问题不同,答案没有帮助。我正在使用第一个选项的答案中描述的技术。不同之处在于我在另一个源文件中强制实例化。 【参考方案1】:

是否可以让“SpecialDataMember.o”保存LinkCollection&lt;SpecialDataMember&gt; 的代码。 SpecialDataMember.h 的每个包含者都应该知道我将 LinkCollection&lt;SpecialDataMember&gt; 留给了链接器。

简单,简单地说:

extern template class LinkCollection<SpecialDataMember>;

在标头中,它告诉编译器不要实例化该模板并将其留给另一个文件。

然后在一个SpecialDataMember.cpp 文件中提供该实例化:

template class LinkCollection<SpecialDataMember>;

【讨论】:

如果在标题中定义了extern template LinkCollection&lt;SpecialDataMember&gt;;template LinkCollection&lt;SpecialDataMember&gt;; 会起作用吗? 是的。就像声明一个函数然后定义它一样工作正常。 extern template 是一个显式的实例化声明,它说“在程序的某个地方会有一个显式的实例化定义”,但它并没有说该定义不能在同一个文件中稍后出现。 @PiotrSkotnicki,不,我只是从问题中复制和粘贴,它丢失了:) 现在已修复,谢谢

以上是关于在另一个标题中强制模板实例化的主要内容,如果未能解决你的问题,请参考以下文章

c++中另一个类中的模板类实例化

如何用 swig 实例化模板类的模板方法?

正确使用函数的显式模板实例化?

有没有办法避免警告/错误模板实例化回溯?

使用 gcc 强制实例化对象

显式实例化模板类的显式实例化模板方法