问题 为什么nullptr_t不是关键字


这是一个声明 nullptr_t 在 <cstddef> :

namespace std {
  typedef decltype(nullptr) nullptr_t;
}

根据 这个std::nullptr_t 是某些未指定的基本类型的别名 nullptr 是一个实例。所以实际的类型 nullptr 没有名字(好吧,语言没有给它起名字,名称由标准库提供)。

nullptr 本身就是一个关键字。但标准没有为类型引入关键字 nullptr。而是使用 decltype(nullptr) 提供。

这样做的原因是什么?我觉得很困惑。您需要包含标头并指定 std:: 仅使用语言内置功能。

这是为了保持C ++关键字的集合尽可能小吗?这是专门为 nullptr 或委员会将宣布所有类似的新类型,所以我们会 namespace std { typedef decltype(false) bool; } 如果早点作出这样的决定?


12784
2017-12-05 15:57


起源

是的,没有什么比在语言中添加新关键字更能破坏现有代码。上下文关键字如 enum class, final, override btw是一个不错的选择。 - Hans Passant
但它也是最容易检测和修复的东西(当然总有病态情况,例如代码生成)。考虑到这一点,可能存在无数更糟糕的方法来破坏现有代码。 - Karoly Horvath
添加新关键字会为现有代码带来潜在的中断,委员会会尽可能避免这些中断。看到 为什么覆盖和最终标识符具有特殊含义而不是保留关键字? 为了不进行覆盖和最终保留字的理由。 - Shafik Yaghmour


答案:


根据最初的提议 nullptrN2431 (重点是我的):

我们提出一个新的标准保留字 nullptr。该 nullptr 关键词   指定一个恒定的rvalue类型 decltype(nullptr)。我们也   提供 typedeftypedef decltype(nullptr) nullptr_t;  nullptr_t 是   不是保留字。 它是一个 typedef (就像它一样 _t  typedef 表示)    decltype(nullptr) 定义于 <cstddef>我们不希望看到太多   在真实程序中直接使用nullptr_t。

一般来说,委员会不愿意在语言中添加新的关键词。在我的拙见中,这是有充分理由的 向后兼容。 

如果您进一步阅读该提案,您会发现主要问题不在于破坏现有代码。

想象一下,如果委员会现在然后引入一个新的关键词会产生什么影响。所有的地狱都会破裂,而C ++从成功故事中解脱出来会是个大笑话。


9
2017-12-05 16:18



但是新的关键字 nullptr 加入。我确信有人已经使用过的机会更高 nullptr 在他们的代码中使用 nullptr_t 因为“我们不希望看到在实际程序中直接使用nullptr_t。” - anton_rh
所以预计会增加新的类型 std 命名空间? - anton_rh
@anton_rh他们提议 nullptr 成为一个关键字。 “我们提出了一个新的标准保留字nullptr。”该名称是在非正式的极点和谷歌搜索后选择的。 - 101010
@anton_rh相信委员会他们是明智的。他们必须考虑我们不了解的事情,并从中做出最好的妥协。 - 101010


我相信原因很简单:标准化委员会希望尽可能避免引入新的关键词(因为,鉴于数十亿行 现有 C ++代码,它可能与某些代码冲突)。

以来 std::nullptr_t  可以定义,它不需要是关键字。

bool  是历史原因的关键字。很可能很早就推出了......

C ++主要是关于遗留软件,因此人类和社会和经济方面的考虑(以及向后兼容性)对标准化委员会来说很重要(通常仅仅是技术原因)。


3
2017-12-05 16:04



我们可以完全避免使用关键字。只是用 std:: 为了一切。 std::int int = 10, while = 0; std::while(int > while) ... - anton_rh
是的,保持向后兼容性有其自身的大问题...... - Karoly Horvath
但是C ++委员会不希望如此。 FWIW PL / 1是一种没有关键字的语言,所以 IF IF=THEN THEN ELSE=IF; 在PL / 1中有效但不可读 - Basile Starynkevitch


在不需要时,可以避免添加新关键字。为什么在可以添加到库中时添加某些语言。

你已经有了类似的事情 sizeof(x) 返回 std::size_t,你还必须包含一个标头来获取typedef。


3
2017-12-05 16:04



我以为 size_t 只是一个typedef unsigned int 或者其他适合平台运行代码的东西。这里没有内置功能。 - anton_rh
@anton - 是的, std::size_t 是一个typedef,就像 std::nullptr_t。 :-)然后编译器可以返回该类型的值 sizeof,就像它可以返回一个值 nullptr,即使typedef都不可见。没有不同! - Bo Persson
我确信 为size_t 映射到现有 命名 类型(如 unsigned int)。那是不同的。虽然找不到它 stddef.h 并且也开始认为它也很神奇...... O_o - anton_rh
找到一个很好的线程,在std :: nullptr_t和std :: size_t之间进行类比: stackoverflow.com/a/20809166/5447906 - anton_rh