"codecvt_utf8_utf16" 和 "codecvt_utf8" 从 UTF-8 转换为 UTF-16 的区别

Difference between "codecvt_utf8_utf16" and "codecvt_utf8" for converting from UTF-8 to UTF-16

我发现了两个代码片段

std::wstring str = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes("some utf8 string");

并且

std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some utf8 string");

它们是否都是将 std::string 中存储的 utf-8 转换为 std::wstring 中的 utf-16 的正确方法?

codecvt_utf8_utf16 完全如其所说:在 UTF-8 和 UTF-16 之间转换,这两种编码都是易于理解且可移植的编码。

codecvt_utf8 在 UTF-8 和 UCS-2/4 之间转换(取决于给定类型的大小)。 UCS-2 和 UTF-16 不是一回事

因此,如果您的目标是在 wchar_t 中存储真正的实际 UTF-16,那么您应该使用 codecvt_utf8_utf16。但是,如果您尝试使用 wchar_t 作为某种 Unicode-ish 之类的东西进行跨平台编码,那么您不能。 UTF-16 facet 总是转换为 UTF-16,而非 Windows 平台上的 wchar_t 通常应为 UTF-32/UCS-4。相比之下,codecvt_utf8 仅转换为 UCS-2/4,但在 Windows 上,wchar_t 字符串 "supposed" 是完整的 UTF-16。

因此,如果没有一些 #ifdef 或模板工作,您就无法编写满足所有平台的代码。在 Windows 上,你应该使用 codecvt_utf8_utf16;在非 Windows 上,您应该使用 codecvt_utf8.

或者更好的是,只需在内部使用 UTF-8 并找到直接采用特定格式而不是平台相关 wchar_t 东西的字符串的 API。