C++ fmt::print 与 fmt::format_to 命名的技术背景?

Posted

技术标签:

【中文标题】C++ fmt::print 与 fmt::format_to 命名的技术背景?【英文标题】:Technical background to the C++ fmt::print vs. fmt::format_to naming? 【发布时间】:2021-09-12 22:59:20 【问题描述】:

为什么是fmt::format_to(OutputIt, ...) 而不是fmt::print(OutputIt, ...)??


我目前正在熟悉 fmt,这是一个现代 C++ 格式化库。

在浏览 API 时,我发现命名有点不连贯,但考虑到我对库的几乎没有经验(以及我对 API 设计的兴趣),我想支持这些命名选择:(@987654322 @)

fmt::format(...) -> std::string 是有道理的,它返回一个格式化的字符串。 然后我们有void fmt::print([stream, ] ...),这在命名方面也很有意义(当然,鉴于printf 的传统)。 但是那么我们有fmt::format_to(OutputIt, ...) -> OutputIt,除了返回类型之外,它类似于print 对流的处理。

现在显然,一个人可以整天骑自行车,但这里的问题不是为什么我们有 formatprint(这对我来说很容易解释),但为什么一个明显(?)行为类似于 write-to-stream-kind 的函数已与 format_... 命名样式捆绑在一起。

所以,正如问题标题已经提出的那样,fmt::print(stream, ...) 在格式化为流时的行为与fmt::format_to(OutputIt, ...) 在格式化为输出迭代器时的行为是否存在技术差异

或者这纯粹是一种风格选择?另外,鉴于GitHube repo 在这里明确列出了fmt 标签,我希望我们能从原始API 的作者那里得到一个权威的答案。

【问题讨论】:

名字很难。 :) 有兴趣看看这是怎么回事。 很难?命名是一个的战场。配有地雷、铁丝网、大炮和战壕。 @RetiredNinja - 就我个人而言,我认为我们需要一个难以命名的标签,但我觉得我在这个标签上是少数 :-D 不知道这是否与您的问题相关,但 fmt 库已符合 C++ 标准,现在为 part of C++20。然而,这个过程完全放弃了print。看起来它实际上从来都不是提案的一部分,即使是first draft。 @Ranoiaetep print 如果您是 #include <fmt/ostream.h>,则使用 std::ostream&。 AFAIK,format_to 不能直接写信给std::ostream& 【参考方案1】:

虽然可以命名format_toprint,但前者在概念上更接近format,而不是printformat_toformat 的泛化,它通过输出迭代器而不是 std::string 写入输出。因此命名反映了这一点。

另一方面,不带流参数的print 写入stdout 和带参数的print 将其推广到任意流。写入流与写入输出迭代器根本不同,因为它涉及额外的缓冲、同步等。其他语言通常使用“打印”来实现此类功能,因此 fmt 遵循此约定。

这变得很模糊,因为您可以有一个写入流的输出迭代器,但即使在那里,当前的命名也反映了正在使用的高级 API。

换句话说,format_to 基本上是一个花哨的 STL 算法(甚至还有类似于 copy/copy_nformat_to_n)而 print 是一个格式化输出函数。

【讨论】:

以上是关于C++ fmt::print 与 fmt::format_to 命名的技术背景?的主要内容,如果未能解决你的问题,请参考以下文章

Golang basic_leamingfmt.Print, fmt.Printf, fmt.Println 的区别

Go 语言变量及常量的定义与使用

Go语言fmt包详解

Go语言中 Print,Println 和 Printf 的区别

go-06-fmt 的格式化输出

go-06-输入和输出