【发布时间】:2018-07-03 15:12:59
【问题描述】:
在 Microsoft implementation 的指南支持库中,我看到以下代码:
template<class T>
class not_null {
...
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr explicit not_null(U&& u) : ptr_(std::forward<U>(u)) {
Expects(ptr_ != nullptr);
}
...
constexpr T get() const {
Ensures(ptr_);
return ptr_;
}
...
T ptr_;
}
gsl::not_null 的所有构造函数都可能会检查这些指针是否为空,但我们仍会在 each 取消引用时检查指针 (ptr_) 的存储值是否为空。鉴于在 C++ 中我们通常不会为不需要的东西付费,我们为什么要进行这项检查?
UP:确保实现如下(使用默认标志):
#define GSL_LIKELY(x) (!!(x))
...
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
...
#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
【问题讨论】:
-
我看到在讨论中记得一些关于该检查的内容应该只在
std::unique_ptr专业化中,以确保 not nullstd::unique_ptr在被取消引用后不会被取消引用移自。不过我还是不喜欢。 -
@FrançoisAndrieux,请参阅有关
Ensures实施的更新。实际上,这取决于标志,我附上了默认标志。据我了解,它实际上在运行时需要一些成本 -
允许移动
not_null(not_null&& other) = default;是原因。也许它应该是不可移动的“not_null” - 或者一些更复杂的解决方案 - 因为它现在正在实施 - 我怀疑我会使用它 -
@PiotrNycz,实际上,就我在标准中看到的而言,移动的对象处于未指定但有效的状态。实验表明指针值在移动时不会改变。
标签: c++ null cpp-core-guidelines guideline-support-library