std::wstring_convert 和 std::wbuffer_convert 有什么区别?

What's the difference between std::wstring_convert and std::wbuffer_convert?

本文关键字:std convert 区别 什么 wstring wbuffer      更新时间:2023-10-16

在头文件区域设置中声明了两个方便的接口:std::wstring_convertstd::wbuffer_convert。然而,没有使用示例。

有没有简明的例子来说明它们的用法和区别?

std::wstring_convert

给定一个以char32_t元素形式保存UTF-32代码单元的std::u32string(也称为std::basic_string<char32_t>),下面是如何将其转换为字节形式的UTF-8代码单元序列:

// Both <locale> and <codecvt> required
std::u32string input = U"Hello, World";
using Codecvt = std::codecvt_utf8<char32_t>;
std::wstring_convert<Codecvt, char32_t> converter;
// throws std::range_error if the conversion fails
std::string result = converter.to_bytes(input);

注意,std::wstring_convert的一个怪癖是,它总是将标准所称的宽字符串(实际上是std::basic_string的任何一种特殊化,包括std::string)转换为字节字符串或从字节字符串转换为字节串,这是std::basic_string<char, std::char_traits<char>, Allocator>形式的特殊化。

源编码和目标编码将取决于所使用的代码转换方面——这里我使用的是来自<codecvt>的一个常用方面。任何代码转换方面都可以,只要它是可破坏的,例如std::codecvt<wchar_t>就不是这样——它有一个受保护的析构函数。

std::wbuffer_convert

这里有一个令人信服的用例:您有一个out对象,它是std::ostream(也称为std::basic_ostream<char>)的一个实例,需要UTF-8编码的文本。因此,例如out << u8"Hello"应该可以正常工作。然而,碰巧的是,您有很多来自程序中其他地方的UTF-32编码的宽字符串(该工作的最佳候选者是std::u32string),您需要将其传递给out。你可以重复使用std::wstring_convert,但它会很快变老。

这是另一种方式:

std::wbuffer<std::codecvt_utf8<char32_t>, char32_t> wout { out.rdbuf() };
std::u32string input = U"Hello";
wout << input;

也就是说,我们可以获得out的视图,它的行为就好像它是std::basic_stream<char32_t>的一个实例,并且期望使用UTF-32编码的文本,并且我们没有更改区域设置(最后一点是这些便利接口最初存在的一个重要原因)。

我认为std::wbuffer_convert是对std::wstring_convert的补充,而不是竞争对手。

作为免责声明,因为我还没有找到支持这些功能或<codecvt>的实现,所以这里的代码完全未经测试:(./sub>