Boost C++ 库

...一个世界上最受推崇、设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

第 18 章 Boost.Lexical_Cast 1.0 - Boost C++ 函数库
PrevUpHomeNext

第 18 章 Boost.Lexical_Cast 1.0

根据 Boost 软件许可证版本 1.0 发布。(参见随附文件 LICENSE_1_0.txt 或在 https://boost.ac.cn/LICENSE_1_0.txt 复制)

有时需要将一个值转换为文字文本形式,例如将一个 int 表示为 std::string,或者反之,将 std::string 解析为一个 int。当在程序内部数据类型和程序外部表示(例如窗口和配置文件)之间进行转换时,这类示例很常见。

标准的 C 和 C++ 库提供了多种设施来执行此类转换。然而,它们在易用性、可扩展性和安全性方面各有不同。

例如,以 atoi 为代表的一系列标准 C 函数存在一些限制:

  • 转换只支持一个方向:从文本到内部数据类型。使用 C 库进行反向转换,要么需要使用不方便且安全性有损的 sprintf 函数,要么需要承担与 itoa 等非标准函数相关的可移植性损失。
  • 支持的类型范围仅是内置数值类型的一个子集,即 intlongdouble
  • 类型范围无法以统一的方式扩展。例如,从字符串表示转换为复数或有理数。

strtol 为代表的标准 C 函数具有相同的基本限制,但提供了对转换过程更精细的控制。然而,对于常见情况,这种控制通常不是必需的,或者根本不使用。 scanf 系列函数提供了更大的控制,但同样缺乏安全性和易用性。

标准 C++ 库提供了 stringstream 来处理正在讨论的这类内存内格式化。它通过文本提供了对 I/O 与任意类型之间格式化和转换的极大控制。然而,对于简单的转换,直接使用 stringstream 可能显得笨拙(引入额外的局部变量,并且丧失了中缀表达式的便捷性)或者晦涩(其中 stringstream 对象在表达式中作为临时对象创建)。Facet 提供了一个全面的概念和设施来控制文本表示,但它们感知到的复杂性和高入门门槛需要极大的投入才能进行简单的转换,并且排除除了少数程序员之外的所有人。

lexical_cast 函数模板提供了一种方便一致的形式,用于支持在文本表示的任意类型之间进行常见的转换。它所提供的简化是在表达式层面实现这些转换的便捷性。对于更复杂的转换,例如需要比 lexical_cast 默认行为更严格的精度或格式控制,建议使用传统的 std::stringstream 方法。对于数值到数值的转换,boost::numeric_cast 可能比 lexical_cast 提供更合理的结果。

关于基于字符串的格式化选项和问题的详细讨论,包括对 stringstreamlexical_cast 等的比较,请参阅 Herb Sutter 的文章 The String Formatters of Manor Farm。另外,也可以看看 性能 部分。


PrevUpHomeNext