如果nullptr_t不是关键字,为什么char16_t和char32_t?
正如为什么是nullptr_t不是关键字所讨论的那样,最好避免引入新的关键字,因为它们可能会破坏向后兼容性。
那么为什么char16_t
和char32_t
关键字可以像这样定义呢?
namespace std { typedef decltype(u'q') char16_t; typedef decltype(U'q') char32_t; }
提案本身解释了原因:允许使用uint_least16_t
和uint_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_t
和char32_t
定义为uint_least16_t
和uint_least32_t
,这使得无法重载这些字符。]
至于为什么他们不在std
名称空间,这是为了与原来的C提议兼容。 C ++禁止C定义出现在它自己的<cuchar>
版本中
[c.strings] / 3
头文件不应该定义types
char16_t
,char32_t
和wchar_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