为什么 not_null 还没有进入 C++ 标准?

Why hasn't not_null made it into the C++ standard yet?

在第 N 次将注释 "// not null" 添加到原始指针后,我再次想知道 not_null 模板发生了什么。

C++ core guidelines 是很久以前创建的,一些东西已经成为标准,例如 std::span(有些像 string_viewstd::array起源于核心指南本身之前,但有时会混为一谈)。鉴于其相对简单,为什么 not_null(或类似的东西)还没有将其纳入标准?

我定期(但可能不彻底)扫描 ISO 邮件,我什至不知道有关于它的建议。


可能会回答我自己的问题。我不记得遇到过任何可以防止我工作的代码中出现错误的情况,因为我们尽量不以这种方式编写代码。

这些指南本身很受欢迎,例如将其制作成 clang-tidy 和 sonar。支持库似乎不太受欢迎。

例如,boost 已在 Linux 上作为软件包从一开始就可用。我不知道 GSL 的任何实现。不过,我认为它在 windows.

上与 Visual C++ 捆绑在一起

既然有人在评论里提问了。

我自己会用它来记录意图。 像 not_null<> 这样的构造可能具有注释所没有的语义值。 尽管我可以看到它的位置,但执行它是次要的。这最好以零开销完成(可能仅在有限数量的情况下在编译时完成)。

我主要考虑原始指针成员变量的情况。我忘记了将指针传递给函数的情况,我总是使用引用来表示非空,也表示“我不取得所有权”。

同样(对于 class 成员)我们也可以记录所有权 owned<> not_owned<>.

我想还有是否允许更改关联对象。不过,这可能太高了。您可以使用引用成员而不是指针来记录这一点。我自己避免引用成员,因为我几乎总是想要可复制和可分配的类型。但是,请参阅 Should I prefer pointers or references in member data? 以了解对此的一些讨论。

另一个维度是另一个实体是否可以修改变量。 “const”表示我保证不修改它。在多线程代码中,我们想说的几乎是相反的。那是“其他代码承诺在我们使用它时不会修改它”(没有显式锁定)但这是偏离主题的......

有一个可能无法解决的重大技术问题,这使得标准化 not_null 成为一个问题:它无法使用 move-only 智能指针。

not_null 最重要的用例是智能指针(对于原始指针,引用通常就足够了,但即便如此,有时引用也不起作用)。 not_null<shared_ptr<T>> 是一个有用的东西,它说明了关于使用此类对象的 API 的一些重要信息。

但是not_null<unique_ptr<T>>不起作用。它不能工作。原因是从唯一指针移动会使旧对象为空。这正是 not_null 应该阻止的。因此,not_null<T> 总是在其包含的 T 上强制复制。哪个...你不能用 unique_ptr 来做,因为那是类型的全部要点。

能够说 API 消耗的 unqiue_ptr 不为空是好的和有用的。但是你实际上不能用 not_null 做到这一点,这在它的效用上造成了漏洞。

只要 move-only 智能指针不能与 not_null 一起使用,标准化 class 就会出现问题。