问题描述
为什么 Boost 中的所有库都不是头文件?换个说法,是什么强制使用.lib/.dll?
Why are all libraries in Boost not headers-only? Saying it differently, what makes the use of .lib/.dll mandatory?
当一个类不能作为模板或有静态字段时?
Is it when a class can't be a template or has static fields?
推荐答案
不同点,我猜.
- 二进制大小.仅标头会给客户端带来大小负担吗?
- 编译时间.仅标头是否意味着编译性能显着下降?
- 运行时性能.仅标头能否提供卓越的性能?
- 限制.设计是否需要仅标头?
还有一点安全
如果 boost 库中有很多可访问的代码,或者编译器无法争论客户端是否可以访问的代码,则必须将其放入最终的二进制文件中.(*)
If there's a lot of reachable code in the boost library, or code about which the compiler can't argue whether it is reachable by the client, it has to be put into the final binary. (*)
在具有包管理(例如基于 RPM 或 .deb)的操作系统上,共享库可能意味着二进制分发大小的大幅减少并具有安全优势:安全修复程序分发速度更快,然后被所有人自动使用.so/.DLL 用户.所以你有一个重新编译和一个重新分发,但是N 奸商.使用仅头文件的库,您有 N 次重新编译、N 次重新分发,总是针对每个修复程序,并且这些 N 中的某些成员在自己已经.
On operating systems that have package management (e.g. RPM- or .deb-based), shared libraries can mean a big decrease in binary distribution size and have a security advantage: Security fixes are distributed faster and are then automatically used by all .so/.DLL users. So you had one recompile and one redistribution, but N profiteers. With a header-only library, you have N recompiles, N redistributions, always for each fix, and some member of those N are huge in themselves already.
(*) 可达这里的意思是潜在执行";
一些 boost 库很大.如果你想要#include
一切,每次你在源文件中改变一点,你必须重新编译你#include
d 的所有内容.
Some boost libraries are huge. If you would #include
it all, each time you change a bit in your source-file, you have to recompile everything you #include
d.
这可以用樱桃采摘的标题来对抗,例如
This can be counter-measured with cherry picked headers, e.g.
#include <boost/huge-boost-library.hpp> // < BAD
#include <boost/huge-boost-library/just-a-part-of-it.hpp> // < BETTER
但有时您真正需要包含的内容已经大到足以削弱您的重新编译.
but sometimes the stuff you really need to include is already big enough to cripple your recompiles.
对策是使其成为静态或共享库,这意味着完全编译一次(直到下一次 boost 更新)".
The countermeasure is to make it a static or shared library, in turn meaning "compile completely exactly once (until the next boost update)".
我们还没有进入全局优化解决所有 C++ 性能问题的时代.为确保向编译器提供所需的所有信息,您可以将内容设为仅标头,并让编译器做出内联决策.
We are still not in an age were global optimization solves all of our C++ performance problems. To make sure you give the compiler all the information it needs, you can make stuff header-only and let the compiler make inlining decisions.
在这方面,请注意,由于 CPU 上的缓存和推测问题,内联并不总是提供卓越的性能.
In that respect, note that inlining gives not always superior performance because of caching and speculation issues on the CPU.
还要注意,这个论点主要是关于可能足够频繁使用的 boost 库,例如人们可以期望 boost::shared_ptr<>
经常使用,从而成为一个相关的性能因素.
Note also that this argument is mostly with regards to boost libraries that might be used frequently enough, e.g. one could expect boost::shared_ptr<>
to be used very often, and thus be a relevant performance factor.
但是考虑真正的和唯一的相关原因 boost::shared_ptr<>
是 header-only ...
But consider the real and only relevant reason boost::shared_ptr<>
is header-only ...
C++ 中的某些东西不能放入库中,即模板和枚举.
Some stuff in C++ can not be put into libraries, namely templates and enumerations.
但请注意,这只是对了一半.您可以为真实的数据结构和算法编写类型安全的模板化接口,而这些接口又在库中具有它们的运行时通用实现.
But note that this is only halfway true. You can write typesafe, templated interfaces to your real data structures and algorithms, which in turn have their runtime-generic implementation in a library.
同样,C++ 中的某些内容应该放入源文件中,如果是 boost,则应放入库中.基本上,这就是可以给出多重定义"的一切.错误,例如 static
成员变量或全局变量.
Likewise, some stuff in C++ should be put into source files, and in case of boost, libraries. Basically, this is everything that would give "multiple definition" errors, like static
member variables or global variables in general.
一些例子也可以在标准库中找到:std::cout
在标准中定义为extern ostream cout;
,所以cout
基本上需要分发定义它一次且仅一次的东西(库或源文件).
Some examples can also be found in the standard library: std::cout
is defined in the standard as extern ostream cout;
, and so cout
basically requires the distribution of something (library or sourcefile) that defines it once and only once.
这篇关于为什么不是所有的 Boost 库都只有头文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!