如果nullptr_t不是关键字,为什么char16_t和char32_t?

正如为什么是nullptr_t不是关键字所讨论的那样,最好避免引入新的关键字,因为它们可能会破坏向后兼容性。

那么为什么char16_tchar32_t关键字可以像这样定义呢?

 namespace std { typedef decltype(u'q') char16_t; typedef decltype(U'q') char32_t; } 

提案本身解释了原因:允许使用uint_least16_tuint_least32_t的基础types进行uint_least32_t 。 如果他们是typedef这是不可能的。

char16_t定义为一个不同的新types,它具有与uint_least16_t相同的大小和表示uint_least16_t 。 同样,将char32_t定义为一个不同的新types,它具有与uint_least32_t相同的大小和表示uint_least32_t

[N1040将char16_tchar32_t定义为uint_least16_tuint_least32_t ,这使得无法重载这些字符。]

至于为什么他们不在std名称空间,这是为了与原来的C提议兼容。 C ++禁止C定义出现在它自己的<cuchar>版本中

[c.strings] / 3

头文件不应该定义typeschar16_tchar32_twchar_t (2.11)。

然后,这些types将需要全局typedef,它带有自己的一系列问题,如

 typedef decltype(u'q') char16_t; namespace foo { typedef int char16_t; } 

std::nullptr_t不是关键字的原因可以在您链接的问题中find

我们不期望在真正的程序中直接使用nullptr_t

这使得nullptr_t成为真正的例外。

由于这样的顽皮的代码:

 typedef uint16_t char16_t; extern char * strndup16to8 (const char16_t* s, size_t n); extern size_t strnlen16to8 (const char16_t* s, size_t n); 

当然,C ++ 11知道的编译器的存在并不排除存在C ++ 03库或大量使用C ++ 03编译器/库的系统或用户。

如果你幸运的话,他们会这样做:

 #if __STDC_VERSION__ < 201112L && __cplusplus < 201103L typedef uint16_t char16_t; #endif