# std::codecvt_utf16

< cpp‎ | locale

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

std::codecvt_utf16 是一个 std::codecvt 平面，封装 UTF-16 编码字节串和 UCS2 或 UTF-32 字符串（取决于 `Elem` 的类型）之间的转换。此 codecvt 平面能用于以二进制模式读或写 UTF-16 文件。

### 模板形参

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

### 成员函数

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

## std::codecvt_utf16::codecvt_utf16

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

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

### 参数

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

## std::codecvt_utf16::~codecvt_utf16

~codecvt_utf16(); |  |

销毁平面。不同于本地环境所管理的平面，此平面的析构函数为公开。

## 继承自 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 标准。

### 示例

下列示例演示拥有 32 位 wchar_t 系统上的 UTF-16le 文件解码。在有 16 位 wchar_t 的系统上，解码第三字符将失败，因为 std::codecvt_utf16<char16_t> 产生 UCS2 而非 UTF-16 。

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

    void prepare_file()
    {
        // UTF-16le 数据（若宿主系统为小端）
        char16_t utf16le[4] ={0x007a,          // 拉丁小写字母 'z' U+007a
                              0x6c34,          // CJK 表意符号 '水' U+6c34
                              0xd834, 0xdd0b}; // 音符 segno U+1d10b
        // 存储于文件
        std::ofstream fout("text.txt");
        fout.write( reinterpret_cast<char*>(utf16le), sizeof utf16le);
    }

    int main()
    {
        prepare_file();
        // 作为字节流打开
        std::wifstream fin("text.txt", std::ios::binary);
        // 应用平面
        fin.imbue(std::locale(fin.getloc(),
           new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));

        for (wchar_t c; fin.get(c); )
                std::cout << std::showbase << std::hex << c << '\n';
    }

输出：

    0x7a
    0x6c34
    0x1d10b

### 参阅

字符转换 | 本地环境定义多字节 (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_utf8 (C++11)(C++17 中弃用) | 在 UTF-8 与 UCS2/UCS4 间转换 (类模板)
codecvt_utf8_utf16 (C++11)(C++17 中弃用) | 在 UTF-8 与 UTF-16 间转换 (类模板)