【问题标题】:What are the tradeoffs between boost::locale and std::locale?boost::locale 和 std::locale 之间的权衡是什么?
【发布时间】:2015-10-29 20:42:26
【问题描述】:

我正在国际化 C++ 中的大型遗留代码库,我面临一个艰难的决定:我应该使用 boost::locale 还是 std c++ 语言环境?

我致力于使用 utf-8。我们必须进行相当广泛的文本处理,虽然它不是我们代码的核心,但它很重要。我们可以完成大部分可能需要做的事情:时间、日期、数字和货币格式、排序规则、正则表达式、子字符串隔离、与 boost::filesystem 的交互、数据库访问等。

introduction to boost::locale 我明白了

  1. 设置全局语言环境有副作用(csv 示例)。它影响 printf 和 boolst lexical_cast。一些第三方库可能会损坏。
  2. 数字格式在某些语言环境中被破坏。
  3. 语言环境名称未标准化。
  4. 许多供应商只提供 C 和 POSIX,因此 GCC 仅支持 Linux 下的本地化。

我无法评估第 1 点的影响,我猜第 2 点如果影响到我们就相当严重,广告 3 和 4 对我们来说没什么大不了的。

社区是否一致认为 Boost::locale 是更好的选择?标准委员会中是否有任何动议来解决 std::locale 的问题?谁能帮助我做出更明智的决定?

也许最重要的是,从一个迁移到另一个是否简单?两人的配合如何?使用 boost 语言环境设置全局语言环境,然后使用 std 设施是否合法?

【问题讨论】:

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


【解决方案1】:

最后,boost 文档很好地回答了我的问题,但您必须阅读一些内容,这有助于比我在发布时更好地理解 std::locale

与标准配合得很好

std::localefacets 的集合。该标准定义了每个语言环境必须提供的一组方面,但除此之外,似乎大部分都留给了实现。这包括语言环境行为和语言环境的名称。

boost::locale 所做的是提供一堆方面,收集到语言环境中,无论平台如何,它们的行为方式都相同(至少如果您使用默认的 ICU 后端)。

所以boost::locale 提供了一组标准化的 std::locale,它们可以跨平台一致地运行,为广泛的文化规范提供完整的 Unicode 支持,并具有一致的命名。在使用非提升 std::locale(即实现提供的语言环境)和 boost::locale 之间切换是微不足道的,因为它们是相同的类型 - 两者都是 std::facets 的集合,尽管实现不同。 boost::locales 可能会更好地做你想做的事。

完整的 Unicode 支持,适用于所有平台上的所有编码
此外,boost::locale 提供了一种通过ICU 访问完整的 unicode 支持的方法,这使您能够获得 ICU 的好处,而无需 ICU 的糟糕(不是 C++ish)接口。

这是有利的,因为对 Unicode 的任何标准支持都很可能通过语言环境框架来实现,并且任何支持 Unicode 的程序也可能需要支持语言环境(例如排序规则)。

关于数字的更理智的行为 最后,boost::locale 解决了在 std::locales 的通常实现中可以合法地称为重大缺陷的问题——任何流格式的数字都将受到语言环境的影响,无论这是否可取——请参阅boost documentation for详细讨论。

因此,如果您使用 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 等)的代码中,这可能是不受欢迎的行为。使用提升语言环境时,您明确指定何时需要语言环境格式,ala:

cout << boost::locale::as::currency << 123.45 << "\n";
cout << boost::locale::as::number << 12345.666 << "\n"

结论

似乎 boost::locale 应该优于系统提供的语言环境。

【讨论】:

    【解决方案2】:

    Boost.Locale 基于 std::locale 框架,但以更正确的语言方式提供了更多选项。

    另外,如果你想在 windows/MSVC 上使用 utf-8,std::locale 是不行的。

    【讨论】:

      猜你喜欢
      • 2012-10-19
      • 2017-09-15
      • 1970-01-01
      • 2012-09-27
      • 2023-03-21
      • 1970-01-01
      • 2011-09-06
      • 2011-06-04
      • 2019-02-14
      相关资源
      最近更新 更多