std::print 和 std::println
一、基本概念
std::print
和 std::println
是 C++23 新增的格式化输出函数,旨在替代传统的 std::cout
链式调用。它们基于 std::format
实现,支持类型安全的格式化字符串,语法更简洁,性能更优15。
-
功能特点:
-
直接输出到
stdout
(默认)或指定的流。 -
std::println
自动在输出末尾添加换行符。 -
支持与
std::format
相同的格式化语法(如{}
占位符)。
-
二、核心特性
1. 格式化输出
std::print
使用 std::format
的规则进行格式化,支持类型推断和复杂格式控制:
#include <print>int main()
{std::print("整数: {}, 浮点数: {:.2f}, 字符串: {}", 42, 3.14159, "Hello");// 输出:整数: 42, 浮点数: 3.14, 字符串: Hello
}
2. 自动刷新行为
-
不显式刷新流:默认情况下,
std::print
和std::println
不会像std::endl
那样强制刷新输出流。刷新行为取决于底层流的缓冲策略(例如,交互式终端可能按行刷新)1。 -
手动刷新:若需强制刷新,仍需使用
std::flush
或std::fflush(stdout)
1。
3. 线程安全性
-
原子性保证:每个
std::print
调用会将格式化后的字符串原子性地写入流,避免多线程下的文本交错问题。 -
多调用需同步:若连续调用多个
std::print
,仍需手动同步(如使用互斥锁)以确保输出顺序。
4. 与 std::cout
的区别
特性 | std::print /std::println | std::cout |
---|---|---|
语法简洁性 | 支持直接格式化字符串 | 需链式调用 << |
性能 | 更高(减少多次流操作) | 较低 |
换行处理 | std::println 自动换行 | 需手动添加 \n 或 endl |
输出目标 | 默认 stdout | 默认 std::cout |
这对cout 来说绝对是暴击,std::print 的易用性和性能简直完爆它。其语法就是Formatting Library
的格式化语法,可参考Using C++20 Formatting Library1。性能对比:
结果显示,printf 与print 几乎要比cout 快三倍,print 默认会打印到stdout。当打印到cout 并同步
标准C 的流时(print_cout_sync),print 大概要快14%;当不同步标准C 的流时(print_cout),依旧要快不少。
三、示例代码
示例 1:基础用法
// 在线编译: https://www.onlinegdb.com/#include <print>int main()
{std::println("Hello, {}!", "C++23"); // 自动换行std::print("当前值: {:<5}, 状态: {}", 42, "OK");// 输出:// Hello, C++23!// 当前值: 42 , 状态: OK
}
输出:
示例 2:多线程安全
#include <print>
#include <thread>
#include <mutex>std::mutex mtx;void thread_func() {std::lock_guard<std::mutex> lock(mtx);std::println("线程 {} 输出", std::this_thread::get_id());
}int main() {std::thread t1(thread_func);std::thread t2(thread_func);t1.join();t2.join();
}
// 输出顺序可能因线程调度而异,但每行内容完整不交错
Formatting Ranges(P2286)
四、实现细节与优化
-
编译时处理:格式化字符串在编译时解析,生成高效代码。
-
内部表优化:为加速格式化(如 Unicode 处理、数字转换),可能生成预计算的整数常量表(如 10 的幂次表)4。
-
性能对比:相比
std::cout
,std::print
减少了多次流操作,适合高频输出场景。
五、注意事项
-
编译器支持:需支持 C++23 的编译器(如 GCC 13+、Clang 17+)。
-
头文件:包含
<print>
。 -
刷新控制:若需确保实时输出(如日志),需手动刷新1。
-
输入功能缺失:C++23 未提供
std::scan
,输入仍需依赖传统方法5。
六、总结
std::print
和 std::println
通过简化语法、提升性能,成为现代 C++ 输出的首选工具。其设计平衡了易用性与效率,尤其适合格式化需求复杂的场景。未来随着 std::scan
的提案推进(目标 C++26),C++ 的 I/O 生态将更趋完善5。