# std::codecvt_utf8

< cpp‎ | locale

定义于头文件 `<codecvt>` |  |
template< class Elem, unsigned long Maxcode = 0x10ffff, std::codecvt_mode Mode = (std::codecvt_mode)0 > class codecvt_utf8 : public std::codecvt<Elem, char, std::mbstate_t>; |  | (C++11 起) (C++17 中弃用)

std::codecvt_utf8 是封装 UTF-8 编码字符串和 UCS2 或 UTF-32 字符串（取决于 `Elem` 类型）间转换的 std::codecvt 平面。此 codecvt 能用于读写文本和二进制的 UTF-8 文件。

### 模板形参

Elem | - | char16_t 、 char32_t 或 wchar_t 之一
Maxcode | - | 此平面将读写而无错误的最大 `Elem` 值
Mode | - | std::codecvt_mode 类型常量

### 成员函数

(构造函数) | 构造新的 `codecvt_utf8` 平面 (公开成员函数)
(析构函数) | 销毁 `codecvt_utf8` 平面 (公开成员函数)

## std::codecvt_utf8::codecvt_utf8

explicit codecvt_utf8( std::size_t refs = 0 ); |  |

构造新的 `std::codecvt_utf8` 平面，传递初始引用计数 `refs` 给基类。

### 参数

refs | - | 链接到该平面的引用数

## std::codecvt_utf8::~codecvt_utf8

~codecvt_utf8(); |  |

销毁平面。不同于 locale 管理的平面，此平面的析构函数是公开的。

## 继承自 std::codecvt

### 成员类型

成员类型 | 定义
`intern_type` | `internT`
`extern_type` | `externT`
`state_type` | `stateT`

### 成员对象

成员名 | 类型
`id` [静态] | std::locale::id

### 成员函数

out | 调用 `do_out` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
in | 调用 `do_in` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
unshift | 调用 `do_unshift` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
encoding | 调用 `do_encoding` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
always_noconv | 调用 `do_always_noconv` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
length | 调用 `do_length` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)
max_length | 调用 `do_max_length` (`std::codecvt<InternT,ExternT,State>` 的公开成员函数)

### 受保护成员函数

do_out [虚] | 从 internT 转换字符串为 externT 转换字符串，如在写入文件时 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_in [虚] | 从 externT 转换字符串为 internT ，如在从文件读取时 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_unshift [虚] | 为不完整转换生成 externT 字符的终止字符序列 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_encoding [虚] | 返回产生一个 internT 字符所需的 externT 字符数，若此值为常数 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_always_noconv [虚] | 测试平面编码是否对所有合法值为恒等转换 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_length [虚] | 计算转换成给定的 internT 缓冲区会消耗的 externT 字符串长度 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)
do_max_length [虚] | 返回能转换成单个 internT 字符的最大 externT 字符数 (`std::codecvt<InternT,ExternT,State>` 的虚受保护成员函数)

## 继承自 std::codecvt_base

成员类型 | 定义
enum result { ok, partial, error, noconv }; | 无作用域枚举类型

枚举常量 | 定义
`ok` | 完成转换而无错误
`partial` | 未转换所有源字符
`error` | 遇到非法字符
`noconv` | 不要求转换，输入与输出类型相同

### 注意

尽管标准要求此版面在 `Elem` 为 16 位时用 UCS2 工作，某些实现用 UTF-16 代替。用语 "UCS2" 已被弃用并被移除 Unicode 标准。

### 示例

下例示例演示 UCS2/UTF-8 间和 UTF-16/UTF-8 间转换的差异：字符串中的字符不是合法的 UCS2 字符。

    #include <iostream>
    #include <string>
    #include <locale>
    #include <codecvt>

    int main()
    {
        // UTF-8 数据。字符 U+1d10b ，音符 segno ，不在 UCS2 中
        std::string utf8 = u8"z\u6c34\U0001d10b";

        // UTF-8 / UTF-16 标标准转换平面
        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
        std::u16string utf16 = utf16conv.from_bytes(utf8);
        std::cout << "UTF16 conversion produced " << utf16.size() << " code units:\n";
        for (char16_t c : utf16)
            std::cout << std::hex << std::showbase << c << '\n';

        // UTF-8 / UCS2 标准转换平面
        std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> ucs2conv;
        try {
            std::u16string ucs2 = ucs2conv.from_bytes(utf8);
        } catch(const std::range_error& e) {
            std::u16string ucs2 = ucs2conv.from_bytes(utf8.substr(0, ucs2conv.converted()));
            std::cout << "UCS2 failed after producing " << std::dec << ucs2.size()<<" characters:\n";
            for (char16_t c : ucs2)
                std::cout << std::hex << std::showbase << c << '\n';
        }
    }

输出：

    UTF16 conversion produced 4 code units:
    0x7a
    0x6c34
    0xd834
    0xdd0b
    UCS2 failed after producing 2 characters:
    0x7a
    0x6c34

### 参阅

字符转换 | 本地环境定义多字节 (UTF-8, GB18030) | UTF-8 | UTF-16
--- | --- | --- | ---
UTF-16 | `mbrtoc16` / `c16rtomb`(有 C11 的 DR488) | `codecvt`<char16_t, char, mbstate_t> `codecvt_utf8_utf16`<char16_t> `codecvt_utf8_utf16`<char32_t> `codecvt_utf8_utf16`<wchar_t> | N/A
UCS2 | `c16rtomb`(无 C11 的 DR488) | `codecvt_utf8`<char16_t> `codecvt_utf8`<wchar_t>(Windows) | `codecvt_utf16`<char16_t> `codecvt_utf16`<wchar_t>(Windows)
UTF-32 | `mbrtoc32` / `c32rtomb` | `codecvt`<char32_t, char, mbstate_t> `codecvt_utf8`<char32_t> `codecvt_utf8`<wchar_t>(非 Windows) | `codecvt_utf16`<char32_t> `codecvt_utf16`<wchar_t>(非 Windows)
系统宽 UTF-32(非 Windows) UCS2(Windows) | `mbsrtowcs` / `wcsrtombs` `use_facet`<`codecvt` <wchar_t, char, mbstate_t>>(`locale`) | 无 | 无

codecvt | 在字符编码间转换，包括 UTF-8、UTF-16、UTF-32 (类模板)
codecvt_mode (C++11)(C++17 中弃用) | 用于改变标准 codecvt 刻面行为的标签 (枚举)
codecvt_utf16 (C++11)(C++17 中弃用) | 在 UTF-16 与 UCS2/UCS4 间转换 (类模板)
codecvt_utf8_utf16 (C++11)(C++17 中弃用) | 在 UTF-8 与 UTF-16 间转换 (类模板)