简体   繁体   English

boost :: lexical_cast <>的Locale不变保证

[英]Locale invariant guarantee of boost::lexical_cast<>

I'm using boost::lexical_cast<std::string>(double) for converting doubles to string, generating JSON serialized byte stream, that is (on remote side) parsed by .NET. 我正在使用boost::lexical_cast<std::string>(double)将双精度转换为字符串,生成JSON序列化字节流,即(在远程端)由.NET解析。

I'm able to force the .NET to use InvariantCulture for parsing, thereby returning predictable result on every possible language. 我能够强制.NET使用InvariantCulture进行解析,从而在每种可能的语言上返回可预测的结果。

However, I was not able to find this guarantee in boost::lexical_cast documentation. 但是,我无法在boost :: lexical_cast文档中找到此保证。 I tried it a little bit, and it works the same way for different locales set. 我尝试了一下,它对于不同的语言环境设置的工作方式相同。 But, I cannot be sure only from few tests, am I missing something in the documentation, or this cannot be guaranted at all, and I have to use something else? 但是,我不能确定只有少数测试,我在文档中遗漏了什么,或者这根本不能保证,我必须使用别的东西?

EDIT: I've found an issue. 编辑:我发现了一个问题。

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

returns 0,15784465 , and that is undesired. 返回0,15784465 ,这是不受欢迎的。 Can I force the boost::lexical_cast<> not to be aware of locales? 我可以强制boost::lexical_cast<>不要知道语言环境吗?

Can I force the boost::lexical_cast<> not to be aware of locales? 我可以强制boost :: lexical_cast <>不要知道语言环境吗?

No, I don't think that is possible. 不,我不认为这是可能的。 The best you can do is call 你能做的最好的就是打电话

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

to set the global locale to the "C" locale as boost::lexical_cast relies on the global locale. 将全局语言环境设置为“C”语言环境,因为boost::lexical_cast依赖于全局语言环境。 However, the problem is if somewhere else in the code the global locale is set to something else before calling boost::lexical_cast , then you still have the same problem. 但是,问题是如果代码中的其他地方在调用boost::lexical_cast之前将全局语言环境设置为其他内容,那么您仍然遇到同样的问题。 Therefore, a robust solution would be imbue a stringstream like so, and you can be always sure that this works: 因此,一个强大的解决方案就是imbue一个像这样的字符串流,你总能确定这是有效的:

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

A better solution to this problem is to use a boost::locale instead of a std::locale as the globale locale. 解决此问题的更好方法是使用boost :: locale而不是std :: locale作为globale语言环境。 From the documentation : 文档

Setting the global locale has bad side effects... it affects even printf and libraries like boost::lexical_cast giving incorrect or unexpected formatting. 设置全局语言环境有不好的副作用...它甚至影响printf和boost :: lexical_cast等库提供不正确或意外的格式。 In fact many third-party libraries are broken in such a situation. 事实上,在这种情况下,许多第三方图书馆都被打破了。 Unlike the standard localization library, Boost.Locale never changes the basic number formatting, even when it uses std based localization backends, so by default, numbers are always formatted using C-style locale. 与标准本地化库不同,Boost.Locale从不更改基本数字格式,即使它使用基于std的本地化后端,因此默认情况下,数字始终使用C样式语言环境进行格式化。 Localized number formatting requires specific flags. 本地化数字格式需要特定标志。

Boost locale requires you to specify explicitly when you want numeric formatting to be locale aware, which is more consistent with recent library decisions like std::money_put. Boost语言环境要求您明确指定何时希望数字格式设置为语言环境,这与最近的库决策(如std :: money_put)更为一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM