Mik*_*ail 49 c++ pointers cpp-core-guidelines guideline-support-library
最近提出了C++核心指南(恭喜!),我担心gsl::not_null
类型.如I.12中所述:声明一个不能为null的指针not_null
:
帮助避免解除引用nullptr错误.通过避免对nullptr进行冗余检查来提高性能.
...
通过声明源代码中的意图,实现者和工具可以提供更好的诊断,例如通过静态分析查找某些类错误,并执行优化,例如删除分支和空测试.
目的很明确.但是,我们已经有了语言功能.不能为null的指针称为引用.虽然引用一旦创建就无法反弹,但这个问题可以解决std::reference_wrapper
.
我gsl::not_null
和之间的主要区别在于,std::reference_wrapper
后者只能用于代替指针,而前者适用于任何事物 - 可nullptr
分配(引自 F.17:使用not_null来表示"null"不是有效值):
not_null
不只是内置指针.它的工作原理为array_view
,string_view
,unique_ptr
,shared_ptr
,和其他类似指针的类型.
我想象功能比较表如下:
T&
:
nullptr
?- 是的std::reference_wrapper<T>
:
nullptr
?- 是的gsl::not_null<T*>
:
nullptr
?- 是的现在这里是问题,最后:
std::reference_wrapper
现在没用了?PS我创建了标签cpp-core-guidelines
,guideline-support-library
为此,我希望正确.
Jos*_*son 31
引用不是不能为null的指针.引用在语义上与指针非常不同.
引用具有值赋值和比较语义; 也就是说,涉及引用的赋值或比较操作读取和写入引用的值.指针具有(违反直觉的)引用赋值和比较语义; 也就是说,涉及指针的赋值或比较操作读取和写入引用本身(即引用对象的地址).
正如您所指出的,引用不能反弹(由于它们的值赋值语义),但reference_wrapper<T>
类模板可以反弹,因为它具有引用赋值语义.这是因为它reference_wrapper<T>
被设计为与STL容器和算法一起使用,并且如果其复制赋值运算符与其复制构造函数不同,则不会正常运行.但是,reference_wrapper<T>
仍然具有值比较语义,如引用,因此当与STL容器和算法一起使用时,它与指针的行为非常不同.例如,set<T*>
可以包含指向具有相同值的不同对象的指针,同时set<reference_wrapper<T>>
可以包含对具有给定值的一个对象的引用.
所述not_null<T*>
类模板具有参考分配和比较的语义,比如一个指针; 它是一种类似指针的类型.这意味着当与STL容器和算法一起使用时,它的行为类似于指针.它不能为空.
所以,除了忘记比较语义之外,你的评估是正确的.并且,reference_wrapper<T>
不会被任何类型的指针类型淘汰,因为它具有类似引用的值比较语义.
Jen*_*ens 10
我认为仍有一些用例std::reference_wrapper
未被覆盖gsl::not_null
.基本上,std::reference_wrapper
镜像引用并具有operator T&
转换,同时not_null
具有指针接口operator->
.我想到的一个用例是在创建线程时:
void funcWithReference(int& x) { x = 42; }
int i=0;
auto t = std::thread( funcWithReference, std::ref(i) );
Run Code Online (Sandbox Code Playgroud)
如果我无法控制funcWithReference
,我就无法使用not_null
.
这同样适用于算法的仿函数,我也必须使用它进行绑定boost::signals
.
归档时间: |
|
查看次数: |
9402 次 |
最近记录: |