17

C++20 引入了std::format. printf比or有什么优势std::cout?我该如何使用它,有人举个例子?

4

2 回答 2

22

与 printf 相比有什么优势

类型安全。对于 printf,程序员必须仔细地将格式说明符与参数的类型相匹配。如果他们犯了错误,程序的行为是不确定的。这是一个非常常见的错误来源,尤其是对于初学者。

公平地说,只要程序员记住/知道如何启用警告,只要使用常量格式字符串,体面的编译器就会诊断出这些错误。无论如何,使用模板参数推导自动选择格式化类型更方便,更安全。

此外,无法扩展 printf 以支持打印类类型。

或 std::cout

流操纵器非常麻烦和冗长,并且具有不一致的行为。一些操纵器是“粘性的”,影响所有后续插入,而其他操纵器只影响单个插入。

可以说,iostream API 中的格式和参数之间缺乏分离使得更难理解(预期的)结果。

我该如何使用它

要么等待你的编译器/标准库实现支持它。或者如果不想等待,请改用原始的非标准版本。然后按照文档进行操作。

规范规范是C++ 标准。还有一些网站展示了该标准,包括以更方便的格式提供的这个库。另一个很好的信息来源是标准提案。非标准版本的存储库(在上一段中链接)也有大量文档,尽管标准中的内容会有所不同。

有人举个例子吗?

给你(改编自 libfmt 的文档):

std::string s = std::format("I'd rather be {1} than {0}.", "right", "happy");
于 2019-11-25T02:54:21.820 回答
13

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();
}
于 2019-11-25T02:44:02.930 回答