C ++仅标头模板库

时间:2011-06-01 11:58:42

标签: c++ templates header-only

看看这个项目(http://www.savarese.com/software/libssrckdtree/),我找到了“C ++ header-only template library”的定义。目前我掌握了基本的C ++知识,但想知道这究竟意味着什么以及为什么这个人在这个项目中使用它

9 个答案:

答案 0 :(得分:12)

这意味着模板的所有定义(函数模板或类模板)仅在标题中。没有.cpp个文件。只有.h个文件(或其他一些扩展名,例如.hpp或根本没有扩展名,例如<vector>string>等等。

C ++编译器要求模板的定义出现在声明它们的同一文件中。因此,仅头文件库既不是静态库,也不是动态库。它的源代码库意味着您可以在标头中看到实现。您已在代码中包含头文件,这些头文件将与库中的标头一起编译。

请注意,使用<vector>string><map>等模板的C ++标准库部分是仅限标头的库。

实际上模板(类模板和函数模板)无法编译成静态或动态库以链接到程序。正如术语本身所说,模板是一个模板;这不是正常的代码;只有在代码传递模板参数(typevalue)中使用它时,编译器才会从函数/类模板中生成可编译的函数/类:

template<typename T>
struct A
{
   T data;
};

struct B
{
   int data;
};

这里,A无法编译成二进制(静态库或动态库),因为编译器不知道T是什么。但B可以编译成二进制,因为编译器有完整的信息。

因此,您可以阅读短语“class template A”,因为:A是一个类的模板。 A本身不是一个阶级。但是B是一个类,它不是模板。

由于无法将类模板A编译为静态或动态库以链接到您的程序,因此A只能作为header-only库提供完整的源代码。同样

答案 1 :(得分:4)

某些库采用必须与项目链接的二进制文件的形式,以及定义可用类或函数的头文件。 “仅限标题的库”将不包含二进制文件,只包含您在源中包含的标题。

模板是根据其特定用途定制的类或函数;它们通常在头文件中定义,因为编译器必须读取它们的源以自定义它们。在确切知道如何使用它之前,您无法将模板编译为二进制文件,因此您将源代码与您自己的代码一起包含在内,然后编译器就可以一起处理它们。

答案 2 :(得分:3)

这确实意味着库仅作为标头重新分发。 要使用它,您只需要在源文件中包含#include它。

答案 3 :(得分:1)

简短的回答是模板很像编译器生成代码的宏。每次实例化时(例如,使用类似std::list<int>的类型),编译器必须使用原始代码在模板类的代码中插入正确的类型(在本例中为int) 。这就是为什么每次必须在.h文件中使用模板类时,模板类都包含在.cpp文件中。

答案 4 :(得分:1)

这意味着所有代码都在头文件中;没有图书馆 与图书馆相关联。这在实践中意味着什么 在最坏的情况下,它意味着作者从来没有 编译代码:-)。最有可能的是,这意味着代码永远不会 已经过编译器,版本和选项的精确组合测试 你使用的,编译时间会增加。在另一 手,这意味着即使作者没有,你也可以使用该库 可以访问与您相同的编译器,并且您不会被迫使用 他编译图书馆时使用的任何选项。要么 或者,如果它是开源的,则不必构建库 自己。

答案 5 :(得分:0)

这意味着库中没有模块,只有标题。这意味着可以使用该库而无需首先编译它以后再链接;只需在您自己的源模块中包含标题。

这种方法的好处是

  1. 包含更容易,因为您不需要在构建系统中指定链接器选项。
  2. 您总是使用与代码的其余部分相同的编译器(选项)编译所有库代码,因为库的函数在您的代码中被内联。
  3. 可能要快得多。
  4. 在这种情况下,容器数据结构是根据它包含的数据类型实现的,因此无法完全编译。

答案 6 :(得分:0)

对于模板库,可以在头文件(.h文件)中提供所有功能,因为传统的编译器需要模板类的完整定义才能实例化给定类型。除非库要提供预先实例化的版本,或者模板库的某些部分不需要模板化,否则无需放入库中。

答案 7 :(得分:0)

它只是“标题”,因为它不包含单独的.cpp文件,只包含.h文件,因此您只需将#include所有库代码放入代码中。

这可能很有用,因为您不必链接静态库which can be very painful

答案 8 :(得分:0)

这意味着您不必在开发的链接阶段链接任何外部库。您只需下载库并使用#include宏来使用该库。它简化了应用程序的部署,但有时会以更长的编译时间为代价。