为什么fmt库不是header-only?

How come the fmt library is not header-only?

我知道可以在 header-only 模式下使用 fmt 格式化库:

但是 - 为什么不只是 header-only,句号?也就是说,在非header-only模式下使用它有什么好处?

vformat 等一些函数不是模板。将它们放在 headers 中并减慢整个编译过程是没有意义的。我想这就是理由。据我所知,fmt 库非常关心编译时间。

what's the benefit of using it in non-header-only mode?

我不是作者,所以我不能代表他们。但是我可以告诉你 not-header-only.

的优点
  • 允许库的headers不包含系统特定的headers,这通常会出现问题,例如使用可能与用户程序冲突的名称定义宏(例如windows.h 可以定义与某些标准库函数重叠的宏)。 Libfmt 实际上利用了这个机会。 OS 特定功能在 header-only 模式中被省略,除非我弄错了。
  • Non-inline 函数通常允许更快 re-builds 以防实现发生变化。这与可能经常这样做的库开发人员非常相关。如果图书馆经常更新,它可能与用户相关。随着库的增长,这一点的重要性也会增加。在无界模板代码的情况下无法利用这一点。这些条件中的大多数可能在 libfmt 的“不太相关或无法利用”方面,这可能是它首先提供 header-only 选项的原因。

正如其他人已经正确指出的那样,主要原因是构建速度。例如,使用静态库(默认)编译比使用 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

在 header-only 中,库的实现细节和依赖关系会泄漏到使用它们的每个翻译单元中。