提升::lexical_cast<>的区域设置不变保证

Locale invariant guarantee of boost::lexical_cast<>

本文关键字:设置 区域 gt cast lt 提升 lexical      更新时间:2023-10-16

我正在使用boost::lexical_cast<std::string>(double)将双精度转换为字符串,生成JSON序列化字节流,即(在远程端)由.NET解析。

我能够强制 .NET 使用 InvariantCulture 进行分析,从而在每种可能的语言上返回可预测的结果。

但是,我无法在 boost::lexical_cast 文档中找到此保证。我尝试了一下,它对于不同的语言环境集的工作方式相同。但是,我不能仅从少数测试中确定,我是否在文档中遗漏了一些东西,或者根本无法保证这一点,我必须使用其他东西?

编辑:我发现了一个问题。

std::locale::global(std::locale("Czech")); 
std::cout << boost::lexical_cast<std::string>(0.15784465) << std::endl;

返回0,15784465,这是不希望的。我可以强制boost::lexical_cast<>不知道区域设置吗?

我可以强制提升::lexical_cast<>不知道区域设置吗?

不,我认为这是不可能的。你能做的最好的事情就是打电话

std::locale::global(std::locale::classic());

将全局区域设置设置为"C"区域设置,因为boost::lexical_cast依赖于全局区域设置。但是,问题是,如果在调用 boost::lexical_cast 之前将代码中的其他地方的全局区域设置设置为其他内容,那么您仍然会遇到同样的问题。因此,一个强大的解决方案是像这样imbue字符串流,并且您始终可以确定这有效:

std::ostringstream oss;
oss.imbue(std::locale::classic());
oss.precision(std::numeric_limits<double>::digits10);
oss << 0.15784465;

此问题的更好解决方案是使用 boost::locale 而不是 std::locale 作为全局语言环境。 从文档中:

设置

全局区域设置有不好的副作用... 它甚至会影响 printf 和库,如 boost::lexical_cast 给出不正确或意外的格式。事实上,许多第三方库在这种情况下被破坏了。 与标准本地化库不同,Boost.Locale 从不更改基本数字格式,即使它使用基于 std 的本地化后端也是如此,因此默认情况下,数字始终使用 C 样式的区域设置进行格式化。本地化的数字格式需要特定的标志。

Boost 区域设置

要求您明确指定何时希望数字格式能够识别区域设置,这与最近的库决策(如 std::money_put)更一致。