【问题标题】:Compile header-only template library into a shared library?将仅标头模板库编译为共享库?
【发布时间】:2011-09-08 13:50:34
【问题描述】:

我们正在设计一个新的 C++ 库,并决定采用基于模板的方法以及针对极端情况的一些特定的部分模板特化。特别是,这将是一个仅包含标头的模板库

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

但是,既然我们知道这将用于有限的类型集,有没有办法将这个头文件编译到一个库中,并提供一个只包含声明而没有其他内容的不同头文件? 请注意,库不仅必须包含通用实现,还必须包含部分专业化..

【问题讨论】:

  • 您的意思是“有限”还是“有界”?显然,您在计算机上或在这个宇宙中所做的任何事情都是有限的,因此区分至关重要。
  • 我的意思是有界的:我们需要为大约 8 种类型实例化这些模板,仅此而已。所以我们可以很容易地写下一个列表。
  • 嗯,我不完全确定,你当然必须提供实际的头文件,但你可以将这些类型的显式实例添加到源文件并编译并声明这些模板@ 987654321@ 其他任何地方。我从未尝试过,但我认为这应该具有预期的效果。

标签: c++ templates shared-libraries


【解决方案1】:

是的。您可以做的是使用编译器的显式模板实例化语法显式实例化 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 的显式实例化中进行了描述:

显式实例化的语法是:

显式实例化

externopttemplate声明

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果真的只有模板,那么就没有共享库。有关具体示例,请参阅各种 Boost 项目。只有当你有非模板代码时,你才会有一个库。一个具体的例子是例如Boost Date_Time 和日期格式化和解析;您可以使用具有或不具有该功能的库,因此可以使用或不使用链接。

      没有共享库在依赖较少的意义上是很好的。缺点是您的二进制文件可能会变得更大,并且您的编译时间成本会更高。但是存储相当便宜(除非您在嵌入式系统中工作是其他特殊情况)并且编译通常是固定的一次性成本。

      【讨论】:

        【解决方案4】:

        虽然没有标准的方法来做到这一点,但通常可以使用特定于实现的技术。我很久以前就用 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 上,因此您必须了解是否以及如何在您的编译器中采用这种方法。我希望这足以让您朝着正确的方向前进。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-28
          • 1970-01-01
          • 2021-02-20
          相关资源
          最近更新 更多