【问题标题】:How come the fmt library is not header-only?为什么 fmt 库不是仅标头?
【发布时间】:2021-08-31 17:03:11
【问题描述】:

我知道可以在仅标题模式下使用fmt 格式化库:

How to use fmt library in the header-only mode?

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

【问题讨论】:

    标签: c++ fmt header-only rationale design-rationale


    【解决方案1】:

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

    在只有头文件的库中,实现细节和依赖项会泄漏到每个使用它们的翻译单元中。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        在非仅标头模式下使用它有什么好处?

        我不是作者,所以我不能代表他们说话。但我可以告诉你 not-header-only 的优点。

        • 允许库的头文件不包含系统特定的头文件,这通常会出现问题,例如定义名称可能与用户程序冲突的宏(例如 windows.h,它可能定义与某些标准库函数重叠的宏)。 Libfmt 实际上确实利用了这个机会。除非我弄错了,否则在仅标头模式下会省略操作系统特定的功能。
        • 非内联函数通常允许更快的重新构建,以防实现更改。这与可能经常这样做的库开发人员非常相关。如果库经常更新,它可能与用户相关。随着图书馆的发展,这一点的重要性也在增加。如果模板代码不受限制,则无法利用这一点。这些条件中的大多数可能与 libfmt 的“不太相关或不能被利用”有关,这可能就是它首先提供仅标头选项的原因。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多