首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gsl::not_null<T*>与std::reference_wrapper<T>对T&

gsl::not_null<T*>与std::reference_wrapper<T>对T&
EN

Stack Overflow用户
提问于 2015-10-23 15:48:38
回答 2查看 16.7K关注 0票数 71

C++ Core Guidelines最近被发布了(恭喜!)我关心的是gsl::not_null类型。如not_null中所述

以避免取消引用nullptr错误。通过避免对nullptr的冗余检查来提高性能。 ..。 通过在源中说明意图,实现者和工具可以提供更好的诊断,例如通过静态分析查找某些类型的错误,并执行优化,例如删除分支和空测试。

意图是明确的。然而,我们已经有了一个语言特性。不能为空的指针称为引用。虽然引用一旦创建就不能反弹,这个问题通过std::reference_wrapper解决了。

我看到gsl::not_nullstd::reference_wrapper的主要区别在于,后者只能用来代替指针,而前者可以用于任何nullptr-assignable (引用null to indicate that "null" is not a valid value):

not_null不仅仅是针对内置指针的。它适用于array_viewstring_viewunique_ptrshared_ptr和其他类似指针的类型.

我认为功能比较表如下所示:

T&

  • 不能存储nullptr?-
  • 可再绑定?- No
  • 可以用来代替指针以外的东西吗?- No

std::reference_wrapper<T>

  • 不能存储nullptr?-
  • 可再绑定?-
  • 可以用来代替指针以外的东西吗?- No

gsl::not_null<T*>

  • 不能存储nullptr?-
  • 可再绑定?-
  • 可以用来代替指针以外的东西吗?-

下面是问题,最后:

  1. 我对这些概念差异的理解正确吗?
  2. 这是否意味着std::reference_wrapper现在是无用的?

PS我为此创建了标记cpp-core-guidelinesguideline-support-library,我希望这是正确的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-30 13:44:59

引用不是不能为空的指针。引用在语义上与指针非常不同。

引用具有值赋值和比较语义;也就是说,涉及引用的赋值或比较操作读取和写入引用值。指针具有(与直觉相反的)引用赋值和比较语义;也就是说,涉及指针的赋值或比较操作读取和写入引用本身(即被引用对象的地址)。

正如您注意到的,引用不能反弹(因为它们的值赋值语义),但是reference_wrapper<T>类模板可以反弹,因为它具有引用赋值语义。这是因为reference_wrapper<T>被设计用于与STL容器和算法一起使用,并且如果它的复制赋值操作符没有执行与其复制构造函数相同的操作,那么它的行为就不会正确。但是,reference_wrapper<T>仍然具有值比较语义,就像引用一样,因此当与STL容器和算法一起使用时,它与指针的行为非常不同。例如,set<T*>可以包含指向具有相同值的不同对象的指针,而set<reference_wrapper<T>>只能包含对一个具有给定值的对象的引用。

not_null<T*>类模板具有引用赋值和比较语义,就像指针一样;它是类似指针的类型。这意味着当与STL容器和算法一起使用时,它的行为就像指针一样。不可能是空的。

所以,你的评估是正确的,除了你忘记了比较语义。不,reference_wrapper<T>不会被任何类型的指针类型所淘汰,因为它具有类似引用的值比较语义。

票数 58
EN

Stack Overflow用户

发布于 2015-10-24 07:32:47

我认为仍然存在std::reference_wrapper的用例,这些用例不在gsl::not_null的范围之内。基本上,std::reference_wrapper镜像一个引用并有一个operator T&转换,而not_null有一个与operator->的指针接口。我立即想到的一个用例是在创建线程时:

代码语言:javascript
复制
void funcWithReference(int& x) { x = 42; }
int i=0;
auto t = std::thread( funcWithReference, std::ref(i) );

如果我不能控制funcWithReference,就不能使用not_null

算法的函子也是如此,我也不得不使用它来绑定boost::signals

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33306553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档