C ++ 17 std :: from_chars和std :: to_chars的目的?

时间:2019-04-26 23:05:29

标签: c++ string language-lawyer c++17

在C ++ 17之前,存在多种将整数,浮点数和双精度数与字符串进行转换的方法。例如,std::stringstreamstd::to_stringstd::atoistd::stoi等可以用来完成这些任务。为此,有很多文章讨论了这些方法之间的区别。

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

首先,这些新功能比以前的方法具有哪些优势和功能?

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

3 个答案:

答案 0 :(得分:9)

std::stringstream是重量级冠军。它考虑了流的imbued locale之类的事情,并且其功能在格式化操作期间涉及诸如constructing a sentry object之类的事情,以便处理与异常相关的问题。 C ++库中的格式化输入和输出操作在being heavyweight, and slow中享有一定声誉。

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同样是轻量级的解析器,不需要进行任何动态分配,也不需要牺牲任何电子来处理语言环境问题或流操作的开销。

答案 1 :(得分:5)

to/from_chars被设计为基本字符串转换函数。与其他方法相比,它们具有两个基本优点。

  1. 它们的重量轻得多。它们从不分配内存(您可以为它们分配内存)。他们从不抛出异常。他们也从不查看语言环境,从而提高了性能。

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

    这些函数甚至可以是constexpr(不是,尽管我不确定为什么不是),而更重量级的分配和/​​或引发版本则不能。

  2. 它们具有明确的往返保证。如果将float转换为字符串,则需要实现来实现,以便采用该确切的字符序列并将其转换回float会产生< em> binary-identical 值。您无法从snprintfstringstreamto_string/stof获得保证。

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

答案 2 :(得分:1)

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