C++20 引入了std::format
. printf
比or有什么优势std::cout
?我该如何使用它,有人举个例子?
2 回答
与 printf 相比有什么优势
类型安全。对于 printf,程序员必须仔细地将格式说明符与参数的类型相匹配。如果他们犯了错误,程序的行为是不确定的。这是一个非常常见的错误来源,尤其是对于初学者。
公平地说,只要程序员记住/知道如何启用警告,只要使用常量格式字符串,体面的编译器就会诊断出这些错误。无论如何,使用模板参数推导自动选择格式化类型更方便,更安全。
此外,无法扩展 printf 以支持打印类类型。
或 std::cout
流操纵器非常麻烦和冗长,并且具有不一致的行为。一些操纵器是“粘性的”,影响所有后续插入,而其他操纵器只影响单个插入。
可以说,iostream API 中的格式和参数之间缺乏分离使得更难理解(预期的)结果。
我该如何使用它
要么等待你的编译器/标准库实现支持它。或者如果不想等待,请改用原始的非标准版本。然后按照文档进行操作。
规范规范是C++ 标准。还有一些网站展示了该标准,包括以更方便的格式提供的这个库。另一个很好的信息来源是标准提案。非标准版本的存储库(在上一段中链接)也有大量文档,尽管标准中的内容会有所不同。
有人举个例子吗?
给你(改编自 libfmt 的文档):
std::string s = std::format("I'd rather be {1} than {0}.", "right", "happy");
C++20std::format
主要只是包含了fmt
许多人已经在使用的库(我们将它用作spdlog
日志框架的一部分)。
因此,如果您想使用它,只需下载fmt
.
至于优点,它具有流的类型安全但没有冗长(legacy-Cprintf
简洁但既不类型安全也不可扩展)。这是我们自己的代码库中的一个示例(稍作修改):
std::string idStr = fmt::format("prefix.{:05d}.suffix", id);
否则需要相当不简洁的标准 C++:
std::string idStr;
{
std::stringstream ss;
ss << "prefix." << std::setfill('0') << std::setw(5) << id << ".suffix";
idStr = ss.str();
}