C++中std::locale::combine返回无名locale却显示名称为'C'的技术疑问
关于std::locale::combine的两个疑问
先看这段代码:
#include <iostream> #include <locale> int main() { std::locale loc = std::locale() .combine<std::numpunct<char>>(std::locale("en_US.UTF-8")); std::cout << loc.name() << '\n'; std::cout << (std::locale() == loc); }
用GCC和Clang编译运行后,输出是C和1。但cppreference明确说明combine()会返回一个新的无名locale,由此产生两个疑问:
1. 为什么combine()返回的locale名称还是'C'?
这是因为你合并的std::numpunct<char> facet在"en_US.UTF-8"和默认的"C" locale中行为完全一致——比如小数点符号、千位分隔符、正负号规则等都没有区别。
GCC和Clang的标准库实现(libstdc++、libc++)会做优化:当合并的facet和原locale的对应facet等价时,不会创建新的无名locale,直接返回原locale。所以最终得到的loc本质上还是"C" locale,name()自然返回C。
只有当合并的facet和原locale的对应facet存在行为差异时,combine()才会生成真正的无名locale,此时name()会返回*(不同实现可能有细微差别,但都是无名标识)。
2. operator==返回1时,怎么区分两个locale?
如果operator==返回1,说明这两个locale的所有facet行为完全等价,从C++标准的角度来说,它们就是同一个locale,不存在需要区分的必要。
如果想验证combine()的合并效果,可以换一个和原locale行为不同的facet进行合并。比如合并中文locale的排序规则facet:
#include <iostream> #include <locale> int main() { std::locale loc = std::locale().combine<std::collate<char>>(std::locale("zh_CN.UTF-8")); std::cout << loc.name() << '\n'; // 输出无名标识,比如"*" std::cout << (std::locale() == loc); // 输出0 }
这时合并后的locale和原"C" locale行为不同,operator==会返回0,name()也会显示为无名locale的标识。
内容的提问来源于stack exchange,提问作者Wei Li
相关产品推荐
相关产品推荐

