为了给出我所说的内容的上下文,下面的程序在使用clang++/libc++编译时正确地打印true
#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.7re.properties/7:
如果
typeid(use_facet<collate<charT> >) == typeid(collate_byname<charT>)和collate_byname<charT>::transform(first, last)返回的排序键的形式是已知的,并且可以转换为主排序键,那么返回该键,否则返回一个空字符串。
原提案解释说,只有当注入的区域设置中的collate方面没有被用户替换时,标准regex_traits::transform_primary()才能工作(这是它知道如何将collate::transform()的结果转换为等效键的唯一方法)。
我的问题是,标准中的typeid比较应该如何确保这一点?这是否意味着使用use_facet从区域设置中提取的所有系统提供的方面都有_byname作为其真正的动态类型?
发布于 2012-07-21 18:39:01
“我的问题是,标准中的类型化比较应该如何确保这一点?这是否意味着使用use_facet从区域设置中提取的所有系统提供的方面都有_byname作为其真正的动态类型?”
为了回答问题的前半部分,typeid比较确保了这一点,因为如果用户用不同的use_facet值实例化了模板,那么typeid比较就会失败。如果typeid的do匹配,则将保证要调度的函数不会被用户覆盖。因此,您将得到系统collate_byname类,并调用适当的转换。
要回答问题的第二部分,这实际上意味着regex预期使用的与区域设置相关的所有系统提供的方面都符合这一实现要求。在同一份文件的前面找到你引用的参考文献28.7
还请注意,在std::locale方面没有可移植的实现transform_primary的方法,因为即使std::collate_byname<>::transform返回的排序密钥格式是已知的,并且可以转换为主排序键,用户仍然可以将自己的自定义std::collate实现安装到所使用的locale对象中,并且可以使用他们认为合适的任何排序密钥格式。因此,transform_primary成员函数对自定义特性类更有用,如果不能为特定的地区实现异常,则应该抛出异常。
简而言之,这告诉我们,如果除了该类型/类型的预期值(即系统提供的值)之外,结果可能是不可预测的,因为用户可以提供不同的排序键格式。通过坚持使用系统提供的值,该方面的类型将被知道,因此排序键将是已知的和可预测的。
发布于 2013-10-15 22:42:41
这是现在的LWG第2338期,我将用决议更新答案。
https://stackoverflow.com/questions/11471932
复制相似问题