std::print 不是 C++23 标准的一部分,因 P2093 提案被推迟至 C++26;当前可用替代方案为 std::format 配合 std::cout 或 printf,或采用第三方 {fmt} 库的 fmt::print。

std::print 在 C++23 中并不比 iostream 或 printf “更好”
它根本不存在——std::print 不是 C++23 标准的一部分。C++23 最终未纳入 头文件和 std::print 函数。提案 P2093(Formatting library enhancements)虽被多次讨论,但因实现分歧、格式字符串处理安全性争议及与 std::format 的重叠,被推迟至 C++26。目前所有主流编译器(GCC 14、Clang 18、MSVC 19.39)均未提供 std::print。
你实际能用的替代方案只有 std::format + std::cout 或 FILE*
真正落地的是 std::format(C++20 引入),它提供类型安全的格式化,但不负责输出。要“打印”,仍需手动搭配流或 C 风格 I/O:
std::cout —— 类型安全,但有流开销;-
std::printf("%s", std::format("Hello, {}!", name).c_str());—— 需注意c_str()生命周期,且放弃std::format对宽字符/本地化的支持; - 第三方库如 {fmt} 提供
fmt::print(),这是当前最接近“理想std::print”的实践选择。
为什么 printf 和 iostream 各自难被取代
性能与安全不是单维度可比的:
-
printf:零分配、无异常、小函数体,但格式字符串与参数类型完全脱节,printf("%d", std::string{})是未定义行为,且不支持用户自定义类型; std::cout :类型安全、可重载、支持 RAII,但默认同步stdin/stdout(std::ios_base::sync_with_stdio(true)),缓冲策略复杂,操作符链式调用易导致临时对象堆积;-
std::format:编译期检查格式说明符(如{}数量)、支持任意可格式化类型、无缓冲副作用,但每次调用都构造std::basic_format_string并可能触发内存分配(尤其含动态宽度/精度时)。
真实项目中该选哪个?看场景
没有银弹,只有权衡:
立即学习“C++免费学习笔记(深入)”;
- 嵌入式或极致性能日志(每微秒敏感):仍用
snprintf+ 静态缓冲,避免任何动态分配; - 服务端应用调试输出:启用
{fmt}的fmt::print,它比std::cout 少一次字符串拷贝,且 API 更简洁; - 需要国际化或宽字符输出:必须用
std::wformat+std::wcout,printf完全不可用; - 已有代码大量使用
std::cout:关闭同步(std::ios_base::sync_with_stdio(false))并搭配std::endl替换为'\n',提升可感知性能,比强行迁移更实际。
#include#include int main() { // ✅ 推荐:类型安全 + 显式控制 std::cout << std::format("Value: {:.2f}, Count: {}", 3.14159, 42) << '\n'; // ❌ 危险:printf 无法校验 std::string 参数 // std::printf("Name: %s\n", std::string{"Alice"}.c_str()); // c_str() 悬垂! // ✅ 安全等价(但多一次拷贝) auto s = std::format("Name: {}", std::string{"Alice"}); std::printf("%s\n", s.c_str()); }
真正要注意的不是“哪个更快”,而是“哪个错误会在运行时崩溃,哪个只在 CI 编译失败”。std::format 把部分错误左移到编译期,但没解决输出本身的线程安全、缓冲区溢出或编码问题——这些得靠你选对载体(std::cout vs FILE*)和用法。











