cppreference说std :: ctype基于经典的“C”语言环境提供字符分类.当我们创建这样的语言环境时,这是否正确:
std::locale loc(std::locale("en_US.UTF8"),new std::ctype<char>);
loc的方面是否仍然会根据“C”语言环境或Unicode语言对字符进行分类?如果按前者分类,为什么我们甚至将语言环境名称指定为“en_US.UTF8”?
解决方法
该标准需要默认构造的std :: ctype< char>通过§22.4.1.3.3匹配最小“C”语言环境[facet.ctype.char.statics] / 1
static const mask* classic_table() noexcept;
Returns: A pointer to the initial element of an array of size
table_size
which represents the classifications of characters in the “C” locale
分类成员函数is()是根据table()定义的,table()是根据classic_table()定义的,除非为ctype< char>的构造函数提供了另一个表
我更新了cppreference以更恰当地匹配这些要求(对于std :: ctype< wchar_t>也说“C”)
要回答第二个问题,使用std :: locale loc(std :: locale(“en_US.UTF8”),new std :: ctype< char>)构建语言环境;将使用您指定的ctype facet(因此,“C”)来对窄字符进行分类,但它是多余的:普通std :: locale(“en_US.UTF8”)的窄字符分类(至少在GNU实现中)是完全相同的:
#include <iostream> #include <cassert> #include <locale> int main() { std::locale loc1("en_US.UTF8"); const std::ctype_base::mask* tbl1 = std::use_facet<std::ctype<char>>(loc1).table(); std::locale loc2(std::locale("en_US.UTF8"),new std::ctype<char>); const std::ctype_base::mask* tbl2 = std::use_facet<std::ctype<char>>(loc2).table(); for(size_t n = 0; n < 256; ++n) assert(tbl1[n] == tbl2[n]); }