transform_primary()和collat​​e_byname()

Cub*_*bbi 24 c++ locale c++11

为了给出我正在讨论的内容,下面的程序true在使用clang ++/libc ++编译时正确打印

#include <iostream>
#include <regex>
int main()
{
    std::locale::global(std::locale("en_US.UTF-8"));
    std::wstring str = L"AÀÁÂÃÄÅaàáâãäå";
    std::wregex re(L"[[=a=]]*", std::regex::basic);
    std::cout << std::boolalpha << std::regex_match(str, re) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

但是,我不太明白std::regex_traits::transform_primary()标准中的描述(通过它[=a=]来处理).引用28.7 [re.traits]/7:

if typeid(use_facet<collate<charT> >) == typeid(collate_byname<charT>)和返回的sort键的形式collate_byname<charT>::transform(first, last)是已知的并且可以转换为主排序键然后返回该键,否则返回一个空字符串.

原来的建议解释说,这个标准regex_traits::transform_primary()如果只能工作collate在充满语言环境方面不是由用户(这是它能够知道如何转换结果的唯一方式取代collate::transform()以等价键).

我的问题是,typeid标准中的比较应如何确保?这是否意味着所有系统提供的方面都脱离了语言环境并use_facet具有_byname真正的动态类型?

joh*_*doe 1

“我的问题是,标准中的 typeid 比较如何确保这一点?这是否意味着所有系统提供的 Facet 从使用 use_facet 的语言环境中取出,都将 _byname 作为其真正的动态类型?”

要回答问题的前半部分, typeid 比较可以确保这一点,因为如果用户使用不同的值实例化模板use_facet,则 typeid 比较将失败。如果 typeid 匹配,将保证要分派的函数不会被用户覆盖。因此,您将获得系统 collat​​e_byname 类,并且将调用正确的转换。

要回答问题的第二部分,它只是意味着与预期由正则表达式使用的语言环境相关的所有系统提供的方面都符合此实现要求。在同一文档的较早部分找到您引用的 28.7 引用

另请注意,没有可移植的方法来根据 std::locale 实现 transform_primary,因为即使 std::collat​​e_byname<>::transform 返回的排序键格式已知并且可以转换为主排序键,用户仍然可以将自己的自定义 std::collat​​e 实现安装到所使用的语言环境对象中,并且可以使用他们认为合适的任何排序键格式。因此,transform_primary 成员函数更多地用于自定义特征类,并且如果无法针对特定语言环境实现它,则应抛出异常。

简而言之,这告诉我们,如果该类型/typeid 没有预期的(即系统提供的)值,则结果可能是不可预测的,因为用户可以提供不同的排序键格式。通过坚持使用系统提供的值,该方面的 typeid 将是已知的,因此排序键将是已知的且可预测的。