C++17 标准::from_chars和标准::to_chars的目的?

C++17 Purpose of std::from_chars and std::to_chars?

本文关键字:chars 标准 to C++17 from      更新时间:2023-10-16

在 C++17 之前,存在多种方法可以将整数、浮点数和双精度转换为字符串和从字符串转换。例如,std::stringstreamstd::to_stringstd::atoistd::stoi等可以用来完成这些任务。对此,有很多帖子讨论这些方法之间的差异。

但是,C++ 17现在引入了std::from_charsstd::to_chars。对此,我想知道引入另一种与字符串之间的转换方法的原因。

首先,与以前的方法相比,这些新功能提供了哪些优势和功能?

不仅如此,这种新的字符串转换方法有什么明显的缺点吗?

std::stringstream是重量级冠军。它考虑了流的灌注区域设置等内容,其功能涉及在格式化操作期间构造哨兵对象等内容,以处理与异常相关的问题。C++库中的格式化输入和输出操作以重量级和缓慢而闻名。

std::to_string的强度低于std::istringstream,但它仍然返回一个std::string,其构造可能涉及动态分配(使用现代短字符串优化技术不太可能,但仍然可能)。而且,在大多数情况下,编译器仍然需要在调用站点生成所有措辞,以支持std::string对象,包括其析构函数。

std::to_chars设计为占用空间尽可能小。您提供缓冲区,除了以特定格式实际将数值格式化到缓冲区之外,std::to_chars几乎没有什么作用,没有任何特定于区域设置的注意事项,唯一的开销是确保缓冲区足够大。使用std::to_chars的代码不需要执行任何动态分配。

std::to_chars在格式选项方面也更加灵活,尤其是浮点值。std::to_string没有格式选项。

std::from_chars同样是一个轻量级解析器,它不需要执行任何动态分配,也不需要牺牲任何电子来处理区域设置问题或流操作的开销。

>to/from_chars被设计为基本的字符串转换函数。与替代方案相比,它们有两个基本优势。

  1. 它们的重量要轻得多。它们从不分配内存(您为其分配内存)。他们从不抛出异常。他们也从不查看区域设置,这也提高了性能。

    基本上,它们的设计使得不可能在 API 级别具有更快的转换函数。

    这些功能甚至可以constexpr(它们不是,尽管我不确定为什么),而更重量级的分配和/或抛出版本则不能。

  2. 他们有明确的往返保证。如果将float/double转换为字符串(没有指定的精度),则需要实现来实现它,以便获取确切的字符序列并将其转换回float/double将生成二进制相同的值。您不会从snprintfstringstreamto_string/stof那里得到保证。

    但是,仅当to_charsfrom_chars调用使用相同的实现时,此保证才有效。因此,您不能期望通过 Internet 将字符串发送到可能使用不同标准库实现编译的其他计算机并获得相同的float。但它确实为您提供了计算机上序列化保证。

所有这些预先存在的方法都必须基于所谓的语言环境来工作。区域设置基本上是一组格式选项,例如,指定哪些字符算作数字、使用什么符号作为小数点、使用什么千位分隔符等等。然而,很多时候,你并不真正需要它。例如,如果您只是在读取 JSON 文件,您就知道数据是以特定方式格式化的,那么没有理由在每次看到'.'时都查找小数点是否应该为小数点。<charconv>中引入的新功能基本上是硬编码的,以根据默认 C 语言环境布局的格式读取和写入数字。没有办法更改格式,但由于格式不必灵活,它们可以非常快......