我正在C++中国际化一个大型遗留代码库,我面临一个困难的决定:我应该使用boost::locale's还是std c++ locale?
我被要求使用utf-8。我们必须进行相当广泛的文本处理,虽然它不是代码的核心,但它很重要。我们可以期望完成大多数可能需要做的事情:时间、日期、数字和货币格式、排序、regexp、子字符串隔离、与boost::filesystem、DB access的交互等等。
我明白的boost简介::locale
我很难评估第1点的影响--我想如果第2点对我们有影响的话,第3和第4点对我们来说不是什么大问题。
社会上是否有共识,推动::地区是更好的选择?标准社区中是否有解决std::locale's问题的动议?有人能帮我做一个更明智的决定吗?
也许最重要的是,从一个迁移到另一个是否很简单?这两个人玩得怎么样?使用boost语言环境设置全局区域设置,然后使用std工具是否合法?
发布于 2015-09-10 13:26:15
最后,boost文档在回答我的问题方面做得很好,但是您必须进行一些阅读,它有助于更好地理解std::locale,而不是我在发帖时的理解。
和std玩得很好
std::locale是facet的集合。标准定义了每个区域设置必须提供的一组方面,但除此之外,似乎大部分都留给实现。这包括区域设置行为和区域设置的名称。
什么促进::区域设置是提供一堆方面,收集到地区,行为相同的方式,无论平台(至少如果你使用默认的ICU后端)。
因此,boost::locale提供了一组标准化的std::locale,它可以跨平台一致地运行,为广泛的文化规范提供完整的Unicode支持,并且具有一致的命名。在使用非boost std::locale (即提供区域设置的实现)和使用boost::locale之间切换非常简单,因为它们是相同的类型--两者都是std::facets的集合,尽管实现是不同的。boost::locale很可能做得更好,做你想做的事情。
完全支持所有平台上的所有编码
此外,boost::locale提供了一种通过ICU访问完整unicode支持的方法,它允许您获得ICU的好处,而不需要ICU的糟糕(而不是C++ish)接口。
这是有利的,因为对Unicode的任何标准支持都很可能是通过locale来实现的,而且任何unicode感知程序也可能需要知道地区(例如,排序规则)。
Saner关于数字的行为--最后,boost::locale解决了通常的std::locales实现中的一个严重缺陷--任何流格式的数字都将受到区域设置的影响,不管这是否可取--有关详细讨论,请参见boost文档。
因此,如果您使用ofstream来读取或写入一个文件,并且已经将globale locale设置为您平台的德语区域设置,那么您将使用逗号分隔浮动的十进制部分。如果您正在读取/编写csv文件,这可能是一个问题。如果使用boost::locale作为全局区域设置,则只有显式地告诉它在数字输入/输出中使用区域设置约定时,才会发生这种情况。请注意,许多库在后台使用区域设置信息,包括boost::lexical_cast。std::to_string也是如此。因此,请考虑以下示例:
std::locale::global(std::locale("de_DE"));
auto demo = [](const std::string& label)
{
std::cout.imbue(std::locale()); // imbue cout with the global locale.
float f = 1234.567890;
std::cout << label << "\n";
std::cout << "\t streamed: " << f << "\n";
std::cout << "\t to_string: " << std::to_string(f) << "\n";
};
std::locale::global(std::locale("C"));//default.
demo("c locale");
std::locale::global(std::locale("de_DE"));//default.
demo("std de locale");
boost::locale::generator gen;
std::locale::global(gen("de_DE.UTF-8"));
demo("boost de locale");给出以下输出:
c locale
streamed: 1234.57
to_string: 1234.567871
std de locale
streamed: 1.234,57
to_string: 1234,567871
boost de locale
streamed: 1234.57
to_string: 1234,567871在实现人工通信(输出到gui或终端)和机器间通信(csv文件、xml等)的代码中,这很可能是不可取的行为。在使用boost语言环境时,可以显式指定何时需要区域设置格式,ala:
cout << boost::locale::as::currency << 123.45 << "\n";
cout << boost::locale::as::number << 12345.666 << "\n"结论
这似乎促进了::地区应该优先于系统提供的地区。
发布于 2015-08-24 06:19:11
Boost.Locale基于std::locale框架,但以更正确的语言方式提供了更多的选项。
另外,如果您想在windows/MSVC上使用utf-8,std::locale是禁止的。
https://stackoverflow.com/questions/31860184
复制相似问题