24

为了给出我正在谈论的内容,以下程序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';
}

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

如果typeid(use_facet<collate<charT> >) == typeid(collate_byname<charT>)返回的排序键的形式collate_byname<charT>::transform(first, last)已知并且可以转换为主排序键,则返回该键,否则返回空字符串。

最初的提案解释说,该标准regex_traits::transform_primary()只有collate在用户没有替换灌输语言环境中的方面时才有效(这是它知道如何将结果转换为collate::transform()等价键的唯一方法)。

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

4

2 回答 2

1

“我的问题是,标准中的 typeid 比较应该如何确保这一点?这是否意味着所有系统提供的方面都从具有 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 将是已知的,因此排序键将是已知的和可预测的。

于 2012-07-21T18:39:01.593 回答
0

这现在是LWG 问题 #2338,我将使用分辨率更新答案。

于 2013-10-15T22:42:41.887 回答