Windows上的wchar_t和char16_t是一样的吗?

avo*_*avo 2 c++ windows unicode winapi char

我有一个实例std::u16string,是否可以将其传递c_str()给Win32 API LPCWSTR,而不需要任何转换?例如,我可以安全地执行此操作:

auto u16s = std::u16string(u"Hello");
::SetWindowTextW(hWnd, reinterpret_cast<LPCWSTR>(u16s.c_str()));    
Run Code Online (Sandbox Code Playgroud)

更新后,MSDN说这里 wchar_t是UTF-16LE,而char16_t只是UTF-16,没有指定endian.是否可以安全地假设char16_t在Windows上也始终是UTF-16LE?或者那将是MSVC编译器特定的,因此如果我与GCC合作,它可能是UTF-32LE(或者可能是UTF-16BE)?

Kin*_*hen 5

虽然他的回答是正确的,但我想对@ jamesdlin的anwser进行修正.

在C++ 11之前,有charwchar_t,因而专注std::basic_string<>std::stringstd::wstring.

但是,宽度(以位为单位)wchar_t是特定于平台的:在Windows上它是16位,而在其他平台上,它是32位.

随着C++ 11的出现,标准增加 char16_t了代表16位宽的字符; 因此在Windows上,std::u16string恰好可以std::wstring在大多数情况下互换,因为它们都能够代表16位宽的字符.

wchar_t类型是实现定义的宽字符类型.在Microsoft编译器中,它表示一个16位宽的字符,用于存储编码为UTF-16LE的Unicode,这是Windows操作系统上的本机字符类型.

但最新的MSDN似乎为代码添加了一些备注,std::wstring但仍打算可移植:

wchar_t的大小是实现定义的.如果您的代码依赖于wchar_t为特定大小,请检查平台的实现(例如,使用sizeof(wchar_t)).如果您需要一个字符串字符类型,其宽度保证在所有平台上保持不变,请使用string,u16string或u32string.

对于LE(little-endian),它应该是特定于体系结构的IIRC.今天大多数架构使用LE.

  • 无论如何,任何关心可移植性的人都应该避免使用 UTF-16。它具有 UTF-8 和 UTF-32 的所有缺点,但没有它们的优点。由于时机不佳,Windows 被 UTF-16 困住了;当微软添加 Unicode 支持时,UTF-8 还不存在。 (3认同)
  • @jam:如果您的可移植代码处理UTF-16编码文件,您当然不应该避免使用UTF-16.使用UTF-16也有一些优点:它是一个固定宽度的编码,适用于各种代码点(整个BMP),并且它可以为某些亚洲脚本提供更紧凑的表示.此外,如果您与Java或.NET接口,UTF-16是一个可行的选择.这是前面提到的两个用作内部字符串表示的内容.在此处选择UTF-16可以减少转化次数. (2认同)