我正在使用C ++对大型遗留代码库进行国际化,我面临一个困难的决定:我应该使用boost :: locale或std c ++ locales吗?
我承诺使用utf-8。我们必须进行相当广泛的文本处理,尽管它不是我们的代码所做的核心,但它很重要。我们可以期望完成人们可能需要做的大部分工作:时间,日期,数字和金钱格式化,整理,正则表达式,子串隔离,与boost :: filesystem的交互,数据库访问等。
introduction to boost::locale我明白了
我无法评估第1点的影响我认为第2点非常严重,如果它影响我们,广告3和4对我们来说不是什么大问题。
社区是否有共识认为Boost :: locale是更好的选择?标准社区中是否有任何动议来解决std :: locale的问题?任何人都可以帮我做出更明智的决定吗?
也许最重要的是,从一个迁移到另一个是否很简单?这两个人互相打得怎么样?使用boost语言环境设置全局语言环境是否合法,然后使用std工具?
答案 0 :(得分:8)
最后,提升文档很好地回答了我的问题,但你必须做一些阅读,并且比发布时更好地理解std::locale
。
与std
很好地配合 std::locale
是facet
的集合。该标准定义了每个语言环境必须提供的一组方面,但除此之外,它似乎最多留给实现。这包括区域设置行为和区域设置的名称。
boost :: locale所做的是提供一系列方面,收集到语言环境中,无论平台如何,行为方式都相同(至少如果您使用默认的ICU后端)。
因此boost::locale
提供了一组标准化的std :: locale,它可以跨平台表现一致,为各种文化规范提供完整的Unicode支持,并具有一致的命名。使用非增强std::locale
(即实现提供的语言环境)和boost::locale
之间的切换是微不足道的,因为它们是相同的类型 - 两者都是std::facets
的集合,尽管实现是不同的。有可能boost::locale
做得更好。
对所有平台上的所有编码都提供完整的Unicode支持
此外,boost::locale
提供了一种通过ICU访问完整unicode支持的方法,这使您可以获得ICU的好处,而无需ICU的差(不是C ++ ish)接口。
这是有利的,因为Unicode的任何标准支持都很可能来自locale frameork,并且任何unicode感知程序也可能需要识别语言环境(例如,用于校对)。
关于数字的Saner行为
最后,boost::locale
解决了在std :: locales的常规实现中可能被合法地称为重要缺陷的问题 - 任何流格式化的数字都将受到语言环境的影响,无论这是否合乎需要 - 请参阅{{ 3}}进行详细讨论。
因此,如果您使用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"
<强>结论强>
似乎boost :: locale&#39; s应优先于系统提供的语言环境。
答案 1 :(得分:2)
Boost.Locale基于std :: locale框架,但以更加语言正确的方式提供了更多选项。
此外,如果你想在windows / MSVC上使用utf-8,std :: locale是不行的。