我正在尝试针对空值进行赋值和测试的编译时检查。原因是我正在使用一个“魔法”非空指针来表示某物的脱离状态,而且很容易忘记它正在使用那个魔法指针并错误地分配和测试 nullptr。 (特别是因为那是代码历史上一直使用的内容。)
认为这是人们已经解决的问题,我搜索并发现 not_null
为 part of the C++ Core Guidelines ,这听起来很有希望。这是 Microsoft 的 MIT 许可实现:
但它只停止对 nullptr 的赋值,而不是比较:
#include <iostream>
#include "include/gsl/gsl"
int main() {
int i;
gsl::not_null<int*> ptr (&i);
/* gsl::not_null<int*> ptr_error (nullptr); */ // this errors
if (ptr != nullptr)
std::cout << "No compile error on compare--this prints\n";
}
那是……不幸的。 :-/
核心指南的目的不是帮助程序员对程序的语义进行编码吗?是否有人针对 null 测试指针并据此做出决策表明他们不知道自己在做什么,并且源代码很可能有错误?
对
not_null
进行哪些细微修改以将其更改为不允许进行这些比较,例如nullptr == ptr
、ptr == nullptr
等等?蛮力我只是= delete;
一些重载到 == 和 != 直到它在我想要的情况下给出错误,但我希望使用预先编写的代码是有人会想到并且更普遍地做到了“正确”。
最佳答案
你可以这样做的原因之一可能是因为有时你可能会得到一个指针/智能指针并想将它与 gsl::not_null
进行比较和/或传递 gsl模板函数中的::not_null
(绝对不知道 gsl::not_null
提供什么):
template<class Lhs, class Rhs>
bool hasSameValue(Lhs lhs, Rhs rhs){
if(lhs == nullptr || rhs == nullptr)
return lhs == rhs;
return *lhs == *rhs;
}
gsl::not_null<int*> ptr = /* [...] */;
shared_ptr<int> sptr = /* [...] */;
hasSameValue(ptr, sptr);
如果您仍想禁止使用 nullptr
进行检查:
bool operator==(std::nullptr_t nptr) = delete;
bool operator!=(std::nullptr_t nptr) = delete;
将它们标记为已删除就足够了。请注意,gsl::not_null
不能继承自定义它们的类才能这样做。如果它继承自一个定义它们的类,只需抛出一个异常(即使它只是一个运行时错误)。
关于c++ - 修改 not_null 以禁止与 nullptr 进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51057099/