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

If nullptr_t isn't a keyword, why are char16_t and char32_t?

本文关键字:char16 char32 为什么 关键字 nullptr 如果      更新时间:2023-10-16

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

既然char16_tchar32_t也可以这样定义,为什么它们是关键词呢?

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

提案本身解释了原因:允许使用uint_least16_tuint_least32_t的底层类型重载。如果他们是typedefed,这是不可能的。

char16_t定义为一个不同的新类型,其大小和表示方式与uint_least16_t相同。同样,将char32_t定义为一个不同的新类型,其大小和表示方式与uint_least32_t相同。

[N1040将char16_tchar32_t定义为uint_least16_tuint_least32_t的typedef,这使得这些字符不可能重载。]

至于它们不在std命名空间中的原因,这是为了与原始C提案兼容。C++禁止C定义出现在自己版本的<cuchar>

[c.strings]/3

标题不应定义类型char16_tchar32_twchar_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