boost :: locale和std :: locale之间有什么权衡?

时间:2015-08-06 15:44:19

标签: c++ regex c++11 boost internationalization

我正在使用C ++对大型遗留代码库进行国际化,我面临一个困难的决定:我应该使用boost :: locale或std c ++ locales吗?

我承诺使用utf-8。我们必须进行相当广泛的文本处理,尽管它不是我们的代码所做的核心,但它很重要。我们可以期望完成人们可能需要做的大部分工作:时间,日期,数字和金钱格式化,整理,正则表达式,子串隔离,与boost :: filesystem的交互,数据库访问等。

introduction to boost::locale我明白了

  1. 设置全局区域设置有副作用(csv示例)。它会影响printf和boolst lexical_cast。一些第三方图书馆可能会破裂。
  2. 在某些区域设置上打破了数字格式。
  3. 区域设置名称未标准化。
  4. 许多供应商只提供C和POSIX,因此GCC仅支持在Linux下进行本地化。
  5. 我无法评估第1点的影响我认为第2点非常严重,如果它影响我们,广告3和4对我们来说不是什么大问题。

    社区是否有共识认为Boost :: locale是更好的选择?标准社区中是否有任何动议来解决std :: locale的问题?任何人都可以帮我做出更明智的决定吗?

    也许最重要的是,从一个迁移到另一个是否很简单?这两个人互相打得怎么样?使用boost语言环境设置全局语言环境是否合法,然后使用std工具?

2 个答案:

答案 0 :(得分:8)

最后,提升文档很好地回答了我的问题,但你必须做一些阅读,并且比发布时更好地理解std::locale

与std

很好地配合

std::localefacet的集合。该标准定义了每个语言环境必须提供的一组方面,但除此之外,它似乎最多留给实现。这包括区域设置行为和区域设置的名称。

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是不行的。