std::print目前仍是实验性特性,未被主流编译器默认支持;当前唯一跨平台、类型安全且带编译期格式校验的方案是std::format配合std::cout。

std::print 本意是替代 printf 和 std::cout
它想解决的两类问题很明确:
-
printf的类型不安全("%s"传std::string就崩)和格式串运行时解析开销 std::cout 的冗长、状态污染(比如 <code>std::hex残留)、无编译期格式校验
但注意:截至 2026 年 10 月,std::print 在 GCC 14.2 / Clang 18 / MSVC 19.39 中仍属实验性实现,多数默认禁用,#include <print></print> 很可能直接报错。你写它,不是写错了,是标准库还没跟上。
现在真正在用的等效替代方案只有 std::format + std::cout
这不是权宜之计,而是当前唯一跨平台、零依赖、类型安全、编译期检查格式串的路径:
-
std::format自 C++20 起已在主流编译器中完整支持(GCC 13+ / Clang 15+ / MSVC 19.30+),无需实验标志 - 格式串必须是字面量:
std::format("x = {}, y = {:.2f}", a, b)✅;std::string fmt = "x = {}"; std::format(fmt, a)❌(编译失败,但正是你要的安全) - 语法与预期中的
std::print完全一致,支持对齐、精度、自定义std::formatter特化 - 若需自动换行,封装一层即可:
template<class args> void println(Args&& args) { std::cout (args)) </class>
别碰 FILE* 或 std::ofstream 的 std::print 重载
标准只定义了两种重载:
-
std::print(format, args)→ 输出到stdout -
std::print(FILE*, format, args)→ 输出到 C 风格文件流(如stderr)
它不接受 std::ofstream、std::ostringstream 等任何 std::basic_ostream 派生类对象。试图写 std::print(my_file, "x = {}", x) 必然触发 no matching function for call to 'print'。
正确做法是解耦:先 std::format 生成字符串,再用 写入流,并务必检查 <code>os.is_open() —— 否则写失败静默丢数据。
第三方 fmt::print 是最接近的“即插即用”方案
如果你能接受引入依赖:
-
fmt::print语法和行为几乎与std::print一致,已稳定多年,性能更好 - 支持
fmt::print(my_file, "x = {}", x)(my_file是std::ofstream) - 需
find_package(fmt REQUIRED)和target_link_libraries(... fmt::fmt),不适合零依赖项目 - 线程安全需自行加锁(
std::mutex),std::osyncstream对它无效
真正容易被忽略的点是:你不是在等一个“更好的函数”,而是在等整个标准库实现同步。现阶段所有对 std::print 的直接使用,本质上都是在赌某家 STL 的私有预览版是否启用、是否稳定、是否线程安全——而生产环境不该押注这个。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











