在https://en.cppreference.com/w/cpp/regex/regex_traits/transform_primary中,提出了以下示例代码段:
#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)
也有人说应该输出true
。但是,始终在Debian上使用GCC 8和Clang 7以及macOS High Sierra随附的Clang进行尝试false
(您可以使用cppreference页面中的“运行”按钮直接进行测试)。
有人可能会说cppreference页面是错误的,这肯定是可能的,但是在阅读文档时,对我来说似乎true
也是正确的输出:str
据我所知,字符串中的所有字符都在的主要整理类中a
。
所以问题是:谁是对的?编译器还是cppreference?又为什么呢?
以下是 g++/libstdc++-9 实现的样子transform_primary
:
template<typename _Fwd_iter>
string_type
transform_primary(_Fwd_iter __first, _Fwd_iter __last) const
{
// TODO : this is not entirely correct.
// This function requires extra support from the platform.
//
// Read http://gcc.gnu.org/ml/libstdc++/2013-09/msg00117.html and
// http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2003/n1429.htm
// for details.
typedef std::ctype<char_type> __ctype_type;
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
std::vector<char_type> __s(__first, __last);
__fctyp.tolower(__s.data(), __s.data() + __s.size());
return this->transform(__s.data(), __s.data() + __s.size());
}
Run Code Online (Sandbox Code Playgroud)
该评论说“不完全正确”;以我的拙见,这个评论不太正确。它应该说“这是完全错误的”,因为事实确实如此。这根本行不通。
libc++-8 顶部的评论说:
// transform_primary is very FreeBSD-specific
Run Code Online (Sandbox Code Playgroud)
事实上,它在 Linux 上根本不起作用(它为所有字符返回一个空字符串)。它可能在 macOS 上运行,它是 FreeBSD 的一种变体,但我附近没有可以检查的。里面可能潜伏着不同的错误。
所以答案是,至少有一些编译器至少在某些时候是错误的。