为什么fmt库不是仅标头?
我知道可以fmt在仅标头模式下使用格式化库:
如何在仅标头模式下使用 fmt 库?
但是 - 为什么不只是标题,句号?也就是说,在 non-header-only 模式下使用它有什么好处?
回答
主要原因是其他人已经正确指出的构建速度。例如,使用静态库(默认)进行编译比使用只有头文件的库快 2.75 倍:
#include <fmt/core.h>
int main() {
fmt::print("The answer is {}.", 42);
}
% time c++ -c test.cc -I include -std=c++11
c++ -c test.cc -I include -std=c++11 0.27s user 0.05s system 97% cpu 0.324 total
% time c++ -c test.cc -I include -std=c++11 -DFMT_HEADER_ONLY
c++ -c test.cc -I include -std=c++11 -DFMT_HEADER_ONLY 0.81s user 0.07s system 98% cpu 0.891 total
在仅标头库中,实现细节和依赖项会泄漏到使用它们的每个翻译单元中。
回答
某些功能如vformat不是模板。将它们放在头文件中并减慢整个编译过程是没有意义的。我想这就是理由。据fmt我所知,图书馆非常关心编译时间。
回答
在非标头模式下使用它有什么好处?
我不是作者,所以我不能代表他们说话。但我可以告诉你 not-header-only 的优点。
- 允许库的头文件不包含系统特定的头文件,这些头文件通常存在一些问题,例如定义宏的名称可能与用户程序冲突(例如 windows.h 可能定义与某些标准库函数重叠的宏)。事实上,Libfmt 确实利用了这个机会。除非我弄错了,否则在仅标头模式中省略了特定于操作系统的功能。
- 非内联函数通常允许在实现更改的情况下更快地重新构建。这与可能经常这样做的库开发人员非常相关。如果库经常更新,它可能与用户相关。随着图书馆的发展,这一点的重要性也会增加。在无界模板代码的情况下无法利用这一点。大多数这些条件可能在 libfmt 的“不太相关或无法利用”方面,这可能是它首先提供仅标头选项的原因。