C++17 标准::from_chars和标准::to_chars的目的?
C++17 Purpose of std::from_chars and std::to_chars?
在 C++17 之前,存在多种方法可以将整数、浮点数和双精度转换为字符串和从字符串转换。例如,std::stringstream
、std::to_string
、std::atoi
、std::stoi
等可以用来完成这些任务。对此,有很多帖子讨论这些方法之间的差异。
但是,C++ 17现在引入了std::from_chars
和std::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
被设计为基本的字符串转换函数。与替代方案相比,它们有两个基本优势。
-
它们的重量要轻得多。它们从不分配内存(您为其分配内存)。他们从不抛出异常。他们也从不查看区域设置,这也提高了性能。
基本上,它们的设计使得不可能在 API 级别具有更快的转换函数。
这些功能甚至可以
constexpr
(它们不是,尽管我不确定为什么),而更重量级的分配和/或抛出版本则不能。 -
他们有明确的往返保证。如果将
float/double
转换为字符串(没有指定的精度),则需要实现来实现它,以便获取确切的字符序列并将其转换回float/double
将生成二进制相同的值。您不会从snprintf
、stringstream
或to_string/stof
那里得到保证。但是,仅当
to_chars
和from_chars
调用使用相同的实现时,此保证才有效。因此,您不能期望通过 Internet 将字符串发送到可能使用不同标准库实现编译的其他计算机并获得相同的float
。但它确实为您提供了计算机上序列化保证。
所有这些预先存在的方法都必须基于所谓的语言环境来工作。区域设置基本上是一组格式选项,例如,指定哪些字符算作数字、使用什么符号作为小数点、使用什么千位分隔符等等。然而,很多时候,你并不真正需要它。例如,如果您只是在读取 JSON 文件,您就知道数据是以特定方式格式化的,那么没有理由在每次看到'.'
时都查找小数点是否应该为小数点。<charconv>
中引入的新功能基本上是硬编码的,以根据默认 C 语言环境布局的格式读取和写入数字。没有办法更改格式,但由于格式不必灵活,它们可以非常快......
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- 标准::变体的赋值运算符
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 如何在 Mac 上使用 c++17 并行标准库算法?
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 并行标准::复制复杂性