55

据我了解,achar可以安全地容纳 ASCII 字符,而char16_t可以char32_t安全地容纳来自 unicode 的字符,一个用于 16 位变体,另一个用于 32 位变体(我应该说“a”而不是“the”吗? ?)。但是我想知道背后的目的wchar_t是什么。我应该在新代码中使用该类型,还是只是为了支持旧代码?wchar_t如果据我了解,如果它的大小不能保证大于 a ,那么旧代码的目的是什么char?澄清会很好!

4

2 回答 2

64

char用于 8 位代码单元、char16_t用于 16 位代码单元和char32_t用于 32 位代码单元。这些中的任何一个都可以用于“Unicode”;UTF-8 使用 8 位代码单元,UTF-16 使用 16 位代码单元,UTF-32 使用 32 位代码单元。


做出的保证wchar_t是语言环境中支持的任何字符都可以从 转换charwchar_t,以及用于 的任何表示形式,无论是char多字节、移位代码、你有什么,都wchar_t将是一个单一的、不同的值。这样做的目的是,您可以wchar_t像使用 ASCII 的简单算法一样操作字符串。

例如,将 ascii 转换为大写如下:

auto loc = std::locale("");

char s[] = "hello";
for (char &c : s) {
  c = toupper(c, loc);
}

但这不会处理将 UTF-8 中的所有字符转换为大写字母,或者将所有其他编码(如 Shift-JIS)中的所有字符。人们希望能够像这样国际化这段代码:

auto loc = std::locale("");

wchar_t s[] = L"hello";
for (wchar_t &c : s) {
  c = toupper(c, loc);
}

所以每个wchar_t都是一个“字符”,如果它有一个大写版本,那么它可以直接转换。不幸的是,这并不是一直都有效。例如,在某些语言中存在奇怪之处,例如德语字母 ß,其中大写版本实际上是两个字符 SS 而不是单个字符。

因此,国际化文本处理本质上比 ASCII 更难,并且不能真正按照设计者wchar_t预期的方式进行简化。因此wchar_t,宽字符通常提供的价值很小。

使用它们的唯一原因是它们已经融入了一些 API 和平台。但是,即使在这样的平台上开发,我也更喜欢在自己的代码中坚持使用 UTF-8,并且只是在 API 边界处转换为所需的任何编码。

于 2013-09-28T16:37:25.580 回答
23

当 Unicode 承诺创建 16 位表示时,该类型wchar_t被纳入标准。大多数供应商选择制造wchar_t32 位,但一家大型供应商选择制造 16 位。由于 Unicode 使用超过 16 位(例如,20 位),我们认为我们应该有更好的字符类型。

for 的目的char16_t是表示 UTF16,并char32_t旨在直接表示 Unicode 字符。但是,在使用wchar_t作为其基本接口的一部分的系统上,您将被wchar_t. 如果您不受约束,我会亲自使用charUTF8 来表示 Unicode。char16_tand的问题char32_t是它们没有得到完全支持,甚至在标准 C++ 库中也不支持:例如,没有直接支持这些类型的流,它比仅仅为这些类型实例化流更有效。

于 2013-09-28T16:06:47.380 回答