std::char_traits
| 
 在标头  
<string> 定义 | 
||
| 
 template< 
    class CharT  | 
||
char_traits 类是一种特征类模板,对给定的字符类型抽象基础字符和字符串比较操作。其所定义的操作集,使得各种泛型算法几乎总是可以基于它实现。从而可以将这些算法用于几乎任何可能的字符或字符串类型,只需提供自定义的 char_traits 类即可。
char_traits 类模板表现为显式实例化的基础。用户可以对任何自定义字符类型提供特化。标准字符类型上已定义了数种特化(见下文),其他特化不需要满足字符特征 (CharTraits) 的要求。
特化
标准库提供以下标准特化:
| 
 在标头  
<string> 定义 | 
|
| std::char_traits<char> | char 的标准字符特征 | 
| std::char_traits<wchar_t> | wchar_t 的标准字符特征 | 
| std::char_traits<char8_t> (C++20) | char8_t 的标准字符特征 | 
| std::char_traits<char16_t> (C++11) | char16_t 的标准字符特征 | 
| std::char_traits<char32_t> (C++11) | char32_t 的标准字符特征 | 
所有这些特化都满足字符特征 (CharTraits) 的要求。
成员类型
标准特化定义了由字符特征 (CharTraits) 要求的以下成员类型:
CharT | 
成员类型 | ||||
|---|---|---|---|---|---|
 char_type  | 
int_type | 
off_type | 
pos_type | 
state_type | 
|
| char | char | int | std::streamoff | std::streampos | std::mbstate_t | 
| wchar_t | wchar_t | std::wint_t | std::wstreampos | ||
| char8_t | char8_t | unsigned int | std::u8streampos | ||
| char16_t | char16_t | std::uint_least16_t | std::u16streampos | ||
| char32_t | char32_t | std::uint_least32_t | std::u32streampos | ||
| 
 另外,标准特化将成员类型   | 
(C++20 起) | 
成员函数
标准特化定义了由字符特征 (CharTraits) 要求的以下静态成员函数:
| 
 [静态] 
 | 
赋值一个字符 (公开静态成员函数)  | 
| 
 [静态] 
 | 
比较两个字符 (公开静态成员函数)  | 
| 
 [静态] 
 | 
移动一个字符序列到另一个上 (公开静态成员函数)  | 
| 
 [静态] 
 | 
复制一个字符序列 (公开静态成员函数)  | 
| 
 [静态] 
 | 
以字典序比较两个字符序列 (公开静态成员函数)  | 
| 
 [静态] 
 | 
返回一个字符序列的长度 (公开静态成员函数)  | 
| 
 [静态] 
 | 
在字符序列中查找一个字符 (公开静态成员函数)  | 
| 
 [静态] 
 | 
转换 int_type 到等价的 char_type(公开静态成员函数)  | 
| 
 [静态] 
 | 
转换 char_type 到等价的 int_type(公开静态成员函数)  | 
| 
 [静态] 
 | 
比较两个 int_type 值(公开静态成员函数)  | 
| 
 [静态] 
 | 
返回一个 eof 值 (公开静态成员函数)  | 
| 
 [静态] 
 | 
检查字符是否为 eof 值 (公开静态成员函数)  | 
注解
字符特征 (CharTraits) 不要求将以上列出的类型和函数定义为直接成员,它只要求类似 X::type 的类型和类似 X::func(args) 的表达式合法并具有要求的语义。用户定义的字符特征可以从其它字符特征派生,并只需要覆盖部分成员,见下方示例。
示例
用户定义的字符特征可以用于提供无关大小写的比较:
#include <cctype> #include <iostream> #include <string> #include <string_view> struct ci_char_traits : public std::char_traits<char> { static char to_upper(char ch) { return std::toupper((unsigned char) ch); } static bool eq(char c1, char c2) { return to_upper(c1) == to_upper(c2); } static bool lt(char c1, char c2) { return to_upper(c1) < to_upper(c2); } static int compare(const char* s1, const char* s2, std::size_t n) { while (n-- != 0) { if (to_upper(*s1) < to_upper(*s2)) return -1; if (to_upper(*s1) > to_upper(*s2)) return 1; ++s1; ++s2; } return 0; } static const char* find(const char* s, std::size_t n, char a) { const auto ua{to_upper(a)}; while (n-- != 0) { if (to_upper(*s) == ua) return s; s++; } return nullptr; } }; template<class DstTraits, class CharT, class SrcTraits> constexpr std::basic_string_view<CharT, DstTraits> traits_cast(const std::basic_string_view<CharT, SrcTraits> src) noexcept { return {src.data(), src.size()}; } int main() { using namespace std::literals; constexpr auto s1 = "Hello"sv; constexpr auto s2 = "heLLo"sv; if (traits_cast<ci_char_traits>(s1) == traits_cast<ci_char_traits>(s2)) std::cout << s1 << " 和 " << s2 << " 相等\n"; }
输出:
Hello 和 heLLo 相等
参阅
| 存储并操作字符序列 (类模板)  | 
|
| 
 (C++17) 
 | 
只读的字符串视图 (类模板)  | 
| 包装给定的抽象设备(std::basic_streambuf) 并提供高层输入接口 (类模板)  | 
|
| 包装给定的抽象设备(std::basic_streambuf) 并提供高层输出接口 (类模板)  | 
|
| 抽象原生设备 (类模板)  |