2011-09-08 59 views
8

我们正在设计一个新的C++库,并决定采用基于模板的方法以及角落案例的一些特定部分模板专业化。特别是,这将是一个标题专用模板库将仅头文件模板库编译为共享库?

现在,有些人担心这会导致大量的二进制文件中代码重复,因为这个模板“图书馆”将被编译成使用它(可以说是唯一的那些部分的任何其他共享库或可执行文件被使用)。我仍然认为这不是问题(特别是,编译器甚至可能会将它无法跨越共享库边界的内联内联)。

然而,由于我们知道的有限集合这将被用于类型,是有办法编译这个头到库中,并提供不同的页眉,只有声明,没有别的?请注意,该库不仅必须包含通用实现,还必须包含部分专业化。

+0

你的意思是“有限”还是“有界”?很明显,你在计算机上或者在这个宇宙中所做的任何事情都是有限的,所以这个区别至关重要。 –

+0

我的意思是有限的:我们将需要约8种类型的这些模板的实例化,不再需要。所以我们可以轻松写下一个列表。 – lytenyn

+0

嗯,我不完全确定,你一定要发布实际的头文件,但你可以添加这些类型的显式实例到源文件并编译并在其他地方声明这些模板'extern'。我从来没有尝试过这个,但我认为这应该会产生预期的效果。 –

回答

6

是的。您可以使用编译器的显式模板实例化语法显式实例化CPP文件中的模板。以下是如何在VC++中使用显式实例:http://msdn.microsoft.com/en-us/library/by56e477(v=VS.100).aspx。 G ++有一个相似的功能:http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html#Template-Instantiation

注意,C++ 11引入了一个标准语法显式实例,在[14.7.2]的FDIS的显式实例描述:

为显式实例的语法是:

显式实例化

extern选择template声明

+1

谢谢,这篇文章也很有帮助:http://anteru.net/2008/11/19/318/ – lytenyn

1

如果它确实是仅限于模板,则不存在共享库。有关具体示例,请参阅各种Boost项目。只有当你有非模板代码,你会有一个库。一个具体的例子是例如Boost Date_Time和日期格式和解析;您可以使用具有或不具有该功能的库,因此可以使用或不使用链接。

从没有共享库的角度来看,它拥有更少的依赖性。不足之处是你的二进制文件可能会变得更大一些,并且你的编译时间成本稍高一些。但是存储相当便宜(除非你在嵌入式系统中工作是其他特殊情况)并且编译通常是固定的一次性成本。

3

C++ Shared Library with Templates: Undefined symbols error 那里的一些答案涵盖了这个话题。总而言之:如果您强制实例化显式共享库代码中的模板,这是可能的。尽管如此,它将需要对共享lib端所有使用的模板的所有使用类型进行明确的规定。

0

虽然目前还没有做一个标准的方法,它通常是可能的实施的具体技术。我很久以前就用Borland的C++ Builder做了它。我们的想法是将您的模板声明为从需要驻留的共享库中导出,并将它们导入到使用位置。我这样做的方式是沿着这些线:

// A.h 
#ifdef GENERATE 
# define DECL __declspec(dllexport) 
#else 
# define DECL __declspec(dllimport) 
#endif 

template <typename T> class DECL C { 
}; 

// A.cpp 
#define GENERATE 
#include "A.h" 

template class DECL A<int>; 

请注意,我没有访问原始代码,因此它可能包含错误。 This blog entry描述了非常类似的方法。

从您的措辞我怀疑你不在Windows上,所以你必须找出是否以及如何采用这种方法与您的编译器。我希望这足以让你走向正确的方向。