【问题标题】:Why are not all Boost libraries header-only?为什么不是所有的 Boost 库都只有标头?
【发布时间】:2012-07-06 13:21:48
【问题描述】:

为什么 Boost 中的所有库都不是仅标头? 换一种说法,是什么让.lib/.dll 的使用成为强制性的?

是不是当一个类不能是模板或者有静态字段的时候?

【问题讨论】:

  • 当特定模块需要使用特定于平台的库时,通常会出现这种情况。例如线程和文件系统。
  • static 班级成员是一个很好的理由,是的。在某些情况下,您只是不想这样做...标题只有优点和缺点。
  • 往往是“不需要做模板”,而不是“不能做模板”。
  • @Vite Falcon:您可以仅针对不同平台的标头实现文件系统功能。是否单头不是目标平台的问题。
  • @phresnel:无论出于何种原因,boost 选择不这样做。同样来自 OP 的问题,我收集到的是“不是所有的库都在标头中,而不必需要库”。由此我推断,为什么他们必须使用 cpp/cxx 文件来创建生成库的代码,以及为什么他们不能在标头中包含这些代码。为此,我推断他们需要为某些库使用特定于平台的库,对我来说,他们的编码指南可能有“不要在 boost 标头中包含特定于平台的标头”。我可能是错的。

标签: c++ boost


【解决方案1】:

不同点,我猜。

  • 二进制大小。仅标头会给客户端带来大小负担吗?
  • 编译时间。仅标头是否意味着编译性能显着下降?
  • 运行时性能。仅标头能否提供卓越的性能?
  • 限制。设计是否只需要标题?

关于二进制大小。

还有一点安全感

如果 boost 库中有很多可访问的代码,或者编译器无法争论客户端是否可以访问的代码,则必须将其放入最终的二进制文件中。 (*)

在具有包管理(例如基于 RPM 或 .deb)的操作系统上,共享库可能意味着二进制分发大小的大幅减少并具有安全优势:安全修复程序分发得更快,然后被所有人自动使用.so/.DLL 用户。所以你有一个重新编译和一个重新分发,但是 N 个奸商。使用仅标头库,您有 N 次重新编译,N 次重新分发,总是针对每个修复程序,并且这些 N 中的一些成员在自己已经。

(*) 此处可到达的意思是“可能执行”

关于编译时间。

一些 boost 库非常庞大。如果你想#include 全部,每次你在源文件中更改一点,你都必须重新编译你#included 的所有内容。

这可以用樱桃采摘的标头来反制,例如

#include <boost/huge-boost-library.hpp> // < BAD
#include <boost/huge-boost-library/just-a-part-of-it.hpp> // < BETTER

但有时您真正需要包含的内容已经大到足以削弱您的重新编译。

对策是使其成为静态或共享库,反过来意味着“完全编译一次(直到下一次 boost 更新)”。

关于运行时性能。

我们还没有到一个全局优化可以解决我们所有的 C++ 性能问题的时代。为确保为编译器提供所需的所有信息,您可以只制作头文件并让编译器做出内联决策。

在这方面,请注意,由于 CPU 上的缓存和推测问题,内联并不总是能提供卓越的性能。

还请注意,此参数主要与可能经常使用的 boost 库有关,例如可以预期boost::shared_ptr&lt;&gt; 会被非常频繁地使用,因此是一个相关的性能因素。

但请考虑真正且唯一相关的原因 boost::shared_ptr&lt;&gt; 仅是标头 ...

关于限制。

C++ 中的某些东西不能放入库中,即模板和枚举。

但请注意,这只是对了一半。您可以为您的真实数据结构和算法编写类型安全的模板化接口,而这些接口又在库中具有它们的运行时通用实现。

同样,C++ 中的一些内容应该放入源文件中,如果是 boost,则应该放入库中。基本上,这就是所有会给出“多重定义”错误的东西,比如static 成员变量或一般的全局变量。

一些例子也可以在标准库中找到:std::cout在标准中定义为extern ostream cout;,所以cout基本上需要something(库或源文件)的分发定义它一次且仅一次

【讨论】:

  • 老实说,我认为只有最后一部分“关于限制”回答了 OP 的问题 :)。但是要注意要包含哪些标头以及运行时性能,这是一个很好的观点。
  • @ViteFalcon 虽然最后一部分回答“为什么不能以其他方式完成”,但其他部分提供了“为什么仅标题库可能不是最好的想法,但在技术上是可能的”。
  • 顺便说一句,我会更改“关于代码大小”标题以提及编译时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 2012-03-09
相关资源
最近更新 更多