说明

std::locale 类对象是一个包含一系列不可变 facets 的索引。c++ 库中的每个输入输出流对象都关联一个 std::locale 对象。通过使用该 locale 中的 facets 来解析和格式化数据。

同时 std::basic_regex 对象也和一个 std::locale 对象关联。

通常 locale 中定义了一些标准的 facets。也可以自己定义 locale。

支持的标准 facets 如下:

char type wchar_t type
std::collate<char> std::collate<wchar_t>
std::ctype<char> std::ctype<wchar_t>
std::codecvt<char, char, mbstate_t> std::codecvt<char32_t, char, mbstate_t>
std::codecvt<char16_t,char,mbstate_t> std::codecvt<wchar_t,char,mbstate_t>
std::moneypunct<char> std::moneypunct<wchar_t>
std::moneypunct<char,true> std::moneypunct<wchar_t,true>
std::money_get<char> std::money_get<wchar_t>
std::money_put<char> std::money_put<wchar_t>
std::numpunct<char> std::numpunct<wchar_t>
std::num_get<char> std::num_get<wchar_t>
std::num_put<char> std::num_put<wchar_t>
std::time_get<char> std::time_get<wchar_t>
std::time_put<char> std::time_put<wchar_t>
std::messages<char> std::messages<wchar_t>

locale 内部实现使用了引用计数,因此对于拷贝是比较高效的,同时对于多线程也是安全的

成员类型

id

class locale::id;

id 是 locale 的一个内部类,作为与 locale facet 对应的唯一 id。每个继承于 std::locale::facet 的类必须包含一个 public 的静态成员对象。每个 locale 对象维护了一个 facets 列表,通过 ids 进行索引。 id 不支持拷贝

#include <iostream>
#include <locale>

struct myfacet : std::locale::facet
{
myfacet(std::size_t refs = 0) : facet(refs) {}
static std::locale::id id;
};

std::locale::id myfacet::id;

int main()
{
std::locale myloc(std::locale(), new myfacet);
std::cout << "has_facet<myfacet>(myloc) returns " << std::boolalpha
<< std::has_facet<myfacet>(myloc) << '\n';
}

facet

class locale::facet;

std::locale::facet 是 locale 内部的一个类,该类是基类,locale 中存储 facet 对象时通过该基类指针进行存储。facet 的实现也使用了引用计数。facet 不支持拷贝

成员对象

locale 中定义了一些 category 的常量

对象名 说明
collate collate facet category 掩码
ctype ctype facet category 掩码
monetary monetary facet category 掩码
numeric numeric facet category 掩码
time time facet category 掩码
messages message facet category 掩码
all `collate ctype monetary numeric time messages `
none 当没有 facet category 时使用此掩码

MSVC 中定义如下:

template <class _Dummy>
class _Locbase { // define templatized category constants, instantiate on demand
public:
static const int collate = 1
static const int ctype = 2;
static const int monetary = 4;
static const int numeric = 8;
static const int time = 16;
static const int messages = 32;
static const int all = 63;
static const int none = 0;
};

成员函数

构造函数

locale() noexcept;
locale(const locale& other) noexcept;
explicit locale(const char* std_name); // 构造一个系统指定名称的 locale
explicit locale(const std::string& std_name); // 构造一个系统指定名称的 locale

// construct a locale by copying, replacing named facets
// 构造 locale,其中 cat 指定部分通过系统指定名称的 locale 中构造,剩余部分通过 other 构造
locale(const locale& other, const char* std_name, category cat);
locale(const locale& other, const std::string& std_name, category cat);

// 构造 locale,f 指定部分从 f 中构造,剩余部分从 other 构造
template<class Facet>
locale(const locale& other, Facet* f);

// 构造 locale,其中 cat 指定的部分从 one 对象里构造,剩余的部分从 other 中构造
locale(const locale& other, const locale& one, category cat);

以上函数除前两个带有 noexcept 的不会抛异常,其余均可能抛异常

operator=

const locale& operator=(const locale& other) noexcept;

combine

template<class Facet>
locale combine(const locale& other) const;

如果 other 中未实现 Facet 则会抛 std::runtime_error 异常

合并两个 locale,其中 Facet type 指定的部分使用 other 中的,其余的使用 *this

name

std::string name() const;

返回系统内部指定的 locale 的名称,例如 “POSIX”, “en_US.UTF8”。如果未定义,则返回 “*”

operator == & operator !=

bool operator==(const locale& other) const;
bool operator!=(const locale& other) const; // (until C++20)

比较两个 locale 是否相等。对于命名 locale,如果名称相等,则认为是相等的。对于未命名 locale,如果底层数据相等则认为相等

operator()

template<class CharT, class Traits, class Alloc>
bool operator()(const basic_string<CharT, Traits, Alloc>& s1,
const basic_string<CharT, Traits, Alloc>& s2) const;

使用 collate facet(std::collate<CharT>) 来比较 s1 和 s2。

global

替换全局 locale 为 loc

static locale global(const locale& loc);

classic

获取 “C” locale 的引用

static const locale& classic();