正如Why is nullptr_t not a keyword所述,最好避免引入新关键字,因为它们会破坏向后兼容性。
为什么char16_t
和char32_t
个关键字,如果它们也可以这样定义?
namespace std {
typedef decltype(u'q') char16_t;
typedef decltype(U'q') char32_t;
}
答案 0 :(得分:25)
The proposal itself解释了原因:允许使用uint_least16_t
和uint_least32_t
的基础类型进行重载。如果他们是typedef
,那么这是不可能的。
将
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)类型。
然后,类型需要是全局typedef,它带有一系列问题,例如
typedef decltype(u'q') char16_t;
namespace foo {
typedef int char16_t;
}
std::nullptr_t
不是关键字的原因可以在您链接的问题中找到
我们不希望在实际程序中直接使用
nullptr_t
。
在这里使nullptr_t
成为真正的例外。
答案 1 :(得分:1)
因为像这样顽皮的代码:
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