gsl :: not_null< T *> vs. std :: reference_wrapper< T>与T& [英] gsl::not_null<T*> vs. std::reference_wrapper<T> vs. T&
问题描述
最近,我提出了 C ++核心指南(congrats!),我非常关心 gsl :: not_null
类型。如 I.12:声明一个不能为null的指针 not_null
:
帮助避免解除引用nullptr错误。要通过
提高性能,避免对nullptr进行冗余检查。
...
通过说明
源中的意图,实现者和工具可以提供更好的诊断,例如
通过静态分析找到一些类错误,并执行
优化,例如删除分支和空测试。
目的很清楚。但是,我们已经有了一个语言功能。不能为空的指针称为引用。虽然引用创建后不能被反弹,但是这个问题可以通过 std :: reference_wrapper
来解决。
gsl :: not_null
与 std :: reference_wrapper之间的主要区别
我看到后者只能用来代替指针,而前者在任何 nullptr
-assignable(quote from F.17:使用not_null表示null不是有效值):
array_view
, string_view
, unique_ptr
, shared_ptr
和其他类指针类型。
我想象功能比较表如下:
T&
:
- 无法存储
nullptr
? - 是 - 可重新绑定? - 否
- 可以使用指针之外的其他方式吗? - 否
std :: reference_wrapper< T>
:
- 无法存储
nullptr
? - 是 - 可重新绑定? - 是
- 可以使用指针以外的其他方式吗? - 否
gsl :: not_null< T *> c $ c>:
- 无法存储
nullptr
? - 是 - 可重新绑定? - 是
- 可以使用指针以外的其他方式吗? - 是
现在是问题,最后是:
- 这些概念之间的区别是否正确?
- 这是否意味着
std :: reference_wrapper $ 我创建了标签
cpp-c $ c>现在没有用了?
<核心指南和 guideline-support-library
为此,我希望正确。
我认为 std :: reference_wrapper
还有用例:: not_null 。基本上, std :: reference_wrapper
镜像一个引用并且具有运算符T&
转换,而 not_null
有一个具有 operator->
的指针接口。一个使用情况立即到我的脑海里是创建一个线程:
void funcWithReference(int& x){x = 42; }
int i = 0;
auto t = std :: thread(funcWithReference,std :: ref(x));
如果我不能控制 funcWithReference
,我不能使用 not_null
。
这同样适用于算法的函子,我不得不使用它 boost :: signals
。
C++ Core Guidelines has been presented recently (congrats!) and I am concerned about gsl::not_null
type. As stated in I.12: Declare a pointer that must not be null as not_null
:
To help avoid dereferencing nullptr errors. To improve performance by avoiding redundant checks for nullptr.
...
By stating the intent in source, implementers and tools can provide better diagnostics, such as finding some classes of errors through static analysis, and perform optimizations, such as removing branches and null tests.
The intent is clear. However, we already have a language feature for that. Pointers that cannot be null are called references. And while references cannot be rebound once they are created, this problem is solved by std::reference_wrapper
.
The main difference between gsl::not_null
and std::reference_wrapper
I see in that the latter can be used only instead of pointers, while the former works on anything nullptr
-assignable (quote from F.17: Use a not_null to indicate that "null" is not a valid value):
not_null
is not just for built-in pointers. It works forarray_view
,string_view
,unique_ptr
,shared_ptr
, and other pointer-like types.
I imagine the feature comparison table like the following:
T&
:
- Cannot store
nullptr
? - Yes - Rebindable? - No
- Can be used instead of something other than pointers? - No
std::reference_wrapper<T>
:
- Cannot store
nullptr
? - Yes - Rebindable? - Yes
- Can be used instead of something other than pointers? - No
gsl::not_null<T*>
:
- Cannot store
nullptr
? - Yes - Rebindable? - Yes
- Can be used instead of something other than pointers? - Yes
Now here are the questions, finally:
- Is my understanding of differences between these concepts correct?
- Does that mean that
std::reference_wrapper
is now useless?
PS I created tags cpp-core-guidelines
and guideline-support-library
for this, I hope properly.
I think that there are still use-cases for std::reference_wrapper
which are not covered by gsl::not_null
. Basically, std::reference_wrapper
mirrors a reference and has a operator T&
conversion, while not_null
has a pointer interface with operator->
. One use-case that comes to my mind immediatly is when creating a thread:
void funcWithReference(int& x) { x = 42; }
int i=0;
auto t = std::thread( funcWithReference, std::ref(x) );
If I don't have control over funcWithReference
, I cannot use not_null
.
The same applies to functors for algorithms, and I had to use it for binding boost::signals
too.
这篇关于gsl :: not_null< T *> vs. std :: reference_wrapper< T>与T&的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!