# std::char_traits

< cpp‎ | string

定义于头文件 `<string>` |  |
template< class CharT > class char_traits; |  |

`char_traits` 类是一种特性类模板，对给定的字符类型抽象基础字符和字符串比较操作。有定义操作集是几乎始终可实现于其项的通用算法。从而可以将这些算法用于几乎任何可能的字符或字符串类型，只需提供自定义的 `char_traits` 类。

`char_traits` 类模板表现为显式实例化的基础。用户可以对任何自定义字符类型提供特化。标准字符类型上已定义了数种特化。

### 标准特化

标准特化的成员 typedef 定义如下。

特化 | `char_type` | `int_type` | `pos_type`
--- | --- | --- | ---
std::char_traits<char> | char | int | std::streampos
std::char_traits<wchar_t> | wchar_t | std::wint_t | std::wstreampos
std::char_traits<char16_t> (C++11) | char16_t | std::uint_least16_t | std::u16streampos
std::char_traits<char32_t> (C++11) | char32_t | std::uint_least32_t | std::u32streampos
std::char_traits<char8_t> (C++20) | char8_t | unsigned int | std::u8streampos

成员类型 | 定义（对所有标准特化相同）
--- | ---
`off_type` | std::streamoff
`state_type` | std::mbstate_t
`comparison_category` (C++20) | std::strong_ordering

标准特化的成员函数的语义定义如下：

特化 | `assign` | `eq` | `lt` | `eof`
--- | --- | --- | --- | ---
std::char_traits<char> | = | `unsigned char` 的 == | `unsigned char` 的 < | EOF
std::char_traits<wchar_t> | = | == | < | WEOF
std::char_traits<char16_t> (C++11) | = | == | < | 非法 UTF-16 编码单元
std::char_traits<char32_t> (C++11) | = | == | < | 非法 UTF-32 编码单元
std::char_traits<char8_t> (C++20) | = | == | < | 非法 UTF-8 编码单元

`char_traits` 类模板的标准特化满足字符特征 (CharTraits) 的要求。

### 成员类型

类型 | 定义
`char_type` | `CharT`
`int_type` | 能保有所有 `char_type` 值加 `EOF` 的整数类型
`off_type` | 实现定义
`pos_type` | 实现定义
`state_type` | 实现定义

### 成员函数

assign [静态] | 赋值一个字符 (公开静态成员函数)
eq lt [静态] | 比较二个字符 (公开静态成员函数)
move [静态] | 移动一个字符序列到另一个上 (公开静态成员函数)
copy [静态] | 复制一个字符序列 (公开静态成员函数)
compare [静态] | 以字典序比较二个字符序列 (公开静态成员函数)
length [静态] | 返回一个字符序列的长度 (公开静态成员函数)
find [静态] | 在字符序列中查找一个字符 (公开静态成员函数)
to_char_type [静态] | 转换 `int_type` 到等效的 `char_type` (公开静态成员函数)
to_int_type [静态] | 转换 `char_type` 到等效的 `int_type` (公开静态成员函数)
eq_int_type [静态] | 比较二个 `int_type` 值 (公开静态成员函数)
eof [静态] | 返回一个 eof 值 (公开静态成员函数)
not_eof [静态] | 检查字符是否为 eof 值 (公开静态成员函数)

### 示例

用户定义的字符特性可以用于提供无关大小写的比较

    #include <string>
    #include <string_view>
    #include <iostream>
    #include <cctype>

    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) {
            auto const 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 << " and " << s2 << " are equal\n";
    }

输出：

    Hello and heLLo are equal

### 参阅

basic_string | 存储并操作字符序列 (类模板)