为什么 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_view
和 std::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 就会出现问题。
在第 N 次将注释 "// not null"
添加到原始指针后,我再次想知道 not_null
模板发生了什么。
C++ core guidelines 是很久以前创建的,一些东西已经成为标准,例如 std::span
(有些像 string_view
和 std::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 就会出现问题。