boost::locale 和 std::locale 之间的权衡是什么?
What are the tradeoffs between boost::locale and std::locale?
我正在使用 C++ 对大型遗留代码库进行国际化,我面临着一个艰难的决定:我应该使用 boost::locale 还是标准 c++ 语言环境?
我承诺使用 utf-8。我们必须进行相当广泛的文本处理,虽然这不是我们代码的核心,但它很重要。我们可以期望完成大部分可能需要做的事情:时间、日期、数字和货币格式、整理、正则表达式、子字符串隔离、与 boost::filesystem 的交互、数据库访问等
introduction to boost::locale我明白了
- 设置全局语言环境有副作用(csv 示例)。它影响 printf 和 boolst lexical_cast。一些第三方库可能会损坏。
- 数字格式在某些语言环境中被破坏。
- 区域名称未标准化。
- 很多厂商只提供C和POSIX,所以GCC只支持Linux下的本地化。
我无法评估第 1 点的影响我猜第 2 点如果对我们有影响的话会相当严重,广告 3 和 4 对我们来说不是什么大问题。
社区是否一致认为 Boost::locale 是更好的选择?标准承诺中是否有任何动议来解决 std::locale 的问题?谁能帮我做出更明智的决定?
也许最重要的是,从一个迁移到另一个是否简单?两人的配合如何?使用 boost locale 设置全局 locale,然后使用 std 设施是否合法?
Boost.Locale 基于 std::locale 框架,但以更正确的语言方式提供了更多选项。
此外,如果您想在 windows/MSVC 上使用 utf-8,std::locale 是不行的。
最后,boost 文档很好地回答了我的问题,但您必须阅读一些内容,这有助于比我在发帖时更好地理解 std::locale
。
与 std 完美搭配
一个std::locale
是facet
的集合。该标准定义了每个语言环境必须提供的一组方面,但除此之外似乎大部分都留给了实现。这包括语言环境行为和语言环境的名称。
boost::locale 所做的是提供一堆方面,收集到语言环境中,无论平台如何,它们的行为都相同(至少如果您使用默认的 ICU 后端)。
因此 boost::locale
提供了一组标准化的 std::locale,它们可以跨平台一致地运行,为广泛的文化规范提供完整的 Unicode 支持,并具有一致的命名。在使用非 boost std::locale
(即提供语言环境的实现)和 boost::locale
之间切换是微不足道的,因为它们是相同的类型——尽管实现不同,但它们都是 std::facets
的集合. boost::locale
很可能会更好地完成您想要的工作。
在所有平台上为所有编码提供完整的 Unicode 支持
此外,boost::locale
提供了一种通过 ICU 访问完整 unicode 支持的方法,它允许您获得 ICU 的好处,而无需 ICU 的糟糕(不是 C++ish)接口。
这是有利的,因为任何对 Unicode 的标准支持很可能来自语言环境框架,并且任何支持 Unicode 的程序也可能需要支持语言环境(例如用于整理)。
关于数字的理智行为
最后,boost::locale
解决了在 std::locales 的通常实现中可以合法地称为重大缺陷的问题——任何流格式的数字都会受到区域设置的影响,无论这是否可取——请参阅boost documentation 进行详细讨论。
因此,如果您使用 ofstream 来读取或写入文件,并且已将全局设置 locale
设置为您平台的德语语言环境,您将使用逗号分隔浮点数的小数部分。如果您是 reading/writing 一个 csv 文件,那可能是个问题。如果您使用 boost::locale
作为您的全局语言环境,只有当您明确告诉它为您的数字 input/output 使用语言环境约定时才会发生这种情况。请注意,许多库在后台使用区域设置信息,包括 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 似乎比系统提供的语言环境更受欢迎。
我正在使用 C++ 对大型遗留代码库进行国际化,我面临着一个艰难的决定:我应该使用 boost::locale 还是标准 c++ 语言环境?
我承诺使用 utf-8。我们必须进行相当广泛的文本处理,虽然这不是我们代码的核心,但它很重要。我们可以期望完成大部分可能需要做的事情:时间、日期、数字和货币格式、整理、正则表达式、子字符串隔离、与 boost::filesystem 的交互、数据库访问等
introduction to boost::locale我明白了
- 设置全局语言环境有副作用(csv 示例)。它影响 printf 和 boolst lexical_cast。一些第三方库可能会损坏。
- 数字格式在某些语言环境中被破坏。
- 区域名称未标准化。
- 很多厂商只提供C和POSIX,所以GCC只支持Linux下的本地化。
我无法评估第 1 点的影响我猜第 2 点如果对我们有影响的话会相当严重,广告 3 和 4 对我们来说不是什么大问题。
社区是否一致认为 Boost::locale 是更好的选择?标准承诺中是否有任何动议来解决 std::locale 的问题?谁能帮我做出更明智的决定?
也许最重要的是,从一个迁移到另一个是否简单?两人的配合如何?使用 boost locale 设置全局 locale,然后使用 std 设施是否合法?
Boost.Locale 基于 std::locale 框架,但以更正确的语言方式提供了更多选项。
此外,如果您想在 windows/MSVC 上使用 utf-8,std::locale 是不行的。
最后,boost 文档很好地回答了我的问题,但您必须阅读一些内容,这有助于比我在发帖时更好地理解 std::locale
。
与 std 完美搭配
一个std::locale
是facet
的集合。该标准定义了每个语言环境必须提供的一组方面,但除此之外似乎大部分都留给了实现。这包括语言环境行为和语言环境的名称。
boost::locale 所做的是提供一堆方面,收集到语言环境中,无论平台如何,它们的行为都相同(至少如果您使用默认的 ICU 后端)。
因此 boost::locale
提供了一组标准化的 std::locale,它们可以跨平台一致地运行,为广泛的文化规范提供完整的 Unicode 支持,并具有一致的命名。在使用非 boost std::locale
(即提供语言环境的实现)和 boost::locale
之间切换是微不足道的,因为它们是相同的类型——尽管实现不同,但它们都是 std::facets
的集合. boost::locale
很可能会更好地完成您想要的工作。
在所有平台上为所有编码提供完整的 Unicode 支持
此外,boost::locale
提供了一种通过 ICU 访问完整 unicode 支持的方法,它允许您获得 ICU 的好处,而无需 ICU 的糟糕(不是 C++ish)接口。
这是有利的,因为任何对 Unicode 的标准支持很可能来自语言环境框架,并且任何支持 Unicode 的程序也可能需要支持语言环境(例如用于整理)。
关于数字的理智行为
最后,boost::locale
解决了在 std::locales 的通常实现中可以合法地称为重大缺陷的问题——任何流格式的数字都会受到区域设置的影响,无论这是否可取——请参阅boost documentation 进行详细讨论。
因此,如果您使用 ofstream 来读取或写入文件,并且已将全局设置 locale
设置为您平台的德语语言环境,您将使用逗号分隔浮点数的小数部分。如果您是 reading/writing 一个 csv 文件,那可能是个问题。如果您使用 boost::locale
作为您的全局语言环境,只有当您明确告诉它为您的数字 input/output 使用语言环境约定时才会发生这种情况。请注意,许多库在后台使用区域设置信息,包括 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 似乎比系统提供的语言环境更受欢迎。