fmtlib/fmt

fmt 是 C++ 语言最受欢迎的格式化库之一,提供类型安全的 printf 风格接口

AI编程开发 部分免费

fmt 是 C++ 语言最受欢迎的格式化库之一,提供类型安全的 printf 风格接口、Python f-string 风格的文本格式化能力,以及高效的字符串格式化操作。与 C 标准库的 printf/sprintf 相比,fmt 在运行时零开销(编译期完成格式化解析)、支持任意用户自定义类型、支持彩色终端输出,且完全兼容 C++11 标准。项目被 LLVM、Microsoftvcpkg、OpenCV、Google TensorFlow 等知名项目采用,GitHub Star 数超过 1.5 万,是现代 C++ 开发的标准工具库之一。

项目简介

fmt 由 C++ 标准委员会成员 Victor Zverovich 创作和维护,最初于 2012 年发布,旨在为 C++ 提供一种既安全(编译期类型检查)又高性能(零运行时开销)的文本格式化方案。fmt 核心是一个仅依赖标准库的 header-only 库(可选独立编译版),通过模板元编程在编译期完成格式化字符串的解析,运行时只执行实际的字符串拼接,性能与手写 printf 几乎无异。fmt 已成为 C++ 社区公认的格式化最佳实践,C++20 的 std::format 标准库即以 fmt 为基础参考实现。

核心功能

编译期类型安全格式化:fmt::format 类似 Python 的 str.format(),在编译期解析格式化字符串并检查参数类型是否匹配,类型不匹配直接报编译错误,而非 printf 的运行时崩溃或乱码输出。

任意类型格式化:只需为自定义类型添加 fmt::formatter 特化(类似 Python 的 format 方法),即可直接用 fmt::format 输出自定义对象,无需手动转换为字符串。fmt 内置支持所有标准库容器、chrono 时间类型、std::optional 等常用类型。

彩色终端输出:fmt 支持终端颜色转义序列(ANSI color codes),开发者可通过 fmt::fg()、fmt::bg()、fmt::emphasis() 等函数为输出文本添加颜色和样式,在日志系统和 CLI 工具中直接输出彩色内容。

本地化支持:fmt 内置 locale 支持(L 修饰符),可输出特定地区的数字格式(千位分隔符、小数点规则等),支持 %Local 格式化指令,比 sprintf 的本地化更易用。

高性能零开销:fmt 的核心是 header-only 的模板库,所有格式化逻辑在编译期内联展开,最终机器码与手写字符拼接相当,不存在 std::ostringstream 的动态内存分配开销。fmt 基准测试显示其性能与 C printf 持平,显著优于 std::ostringstream 和 {fmt} 的竞品。

技术实现

fmt 的核心是编译期格式化解析器。格式化字符串(如 "Hello, {0}! You have {1} new messages.")在编译时通过模板元编程被解析为一棵 AST(抽象语法树),运行时只需遍历 AST 并调用各类型的 format_to 方法将参数写入输出缓冲区。

自定义类型的格式化通过偏特化 fmt::formatter 结构体实现,开发者只需实现 parse()(解析格式化规格)和 format()(输出)两个方法即可。例如为自定义 Date 结构体添加格式化支持:

template struct fmt::formatter { auto parse(format_parse_context& ctx) { return ctx.begin(); } auto format(const Date& d, format_context& ctx) { return format_to(ctx.out(), "{:04d}-{:02d}-{:02d}", d.year, d.month, d.day); } };

快速上手

第一步,header-only 方式引入(无需编译):在 C++ 文件中添加 #include ,编译时加上 -DFMT_HEADER_ONLY;

第二步,使用 format 或 print:

include

int main() { std::string s = fmt::format("Pi is approximately {:.5f}", 3.1415926); fmt::print("Hello, {}!n", "World"); }

第三步,自定义类型格式化:为目标类型添加 fmt::formatter 特化后,即可直接用于 fmt::format;

第四步,使用 FMT_STRING 宏启用编译期格式化字符串检查(推荐生产环境使用),任何类型不匹配都会在编译时报错。

适用人群

C++ 后端工程师:在高性能服务、日志系统、游戏引擎等场景中使用 fmt 替代 printf,获得类型安全的同时不损失性能; 开源库作者:在库代码中使用 fmt 作为格式化方案,避免引入大型依赖,同时保证与用户代码的二进制兼容; CLI 工具开发者:利用 fmt 的彩色输出和本地化支持,快速构建格式化的命令行界面输出,无需依赖 ncurses 等重库。

团队信息

由 AI 猎手自动发现

评论与建议

0 条评论