如果nullptr_t不是关键字,为什么char16_t和char32_t?
If nullptr_t isn't a keyword, why are char16_t and 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
的底层类型重载。如果他们是typedef
ed,这是不可能的。
将
char16_t
定义为一个不同的新类型,其大小和表示方式与uint_least16_t
相同。同样,将char32_t
定义为一个不同的新类型,其大小和表示方式与uint_least32_t
相同。[N1040将
char16_t
和char32_t
定义为uint_least16_t
和uint_least32_t
的typedef,这使得这些字符不可能重载。]
至于它们不在std
命名空间中的原因,这是为了与原始C提案兼容。C++禁止C定义出现在自己版本的<cuchar>
中
[c.strings]/3
标题不应定义类型
char16_t
、char32_t
和wchar_t
(2.11)。
然后类型需要是全局typedefs,这会带来自己的一组问题,如
typedef decltype(u'q') char16_t;
namespace foo {
typedef int char16_t;
}
std::nullptr_t
不是关键字的原因可以在您链接的问题中找到
我们不希望在实际程序中看到
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