当前位置: 首页 > news >正文

做网站论坛php做网站python做什么

做网站论坛,php做网站python做什么,网站开发常用单词,中国建设网官方网站地址左值与右值 序言概念左值和右值的划分理解右值引用常量左值引用与右值引用 移动语义引用折叠完美转发 参考资料 序言 虽然平常都算是了解左值,右值的用法,但是好记性不如烂笔头,记下来供大家评鉴,有错改错,有善赞善&a…

左值与右值

  • 序言
  • 概念
    • 左值和右值的划分理解
    • 右值引用
      • 常量左值引用与右值引用
    • 移动语义
    • 引用折叠
    • 完美转发
  • 参考资料

序言

虽然平常都算是了解左值,右值的用法,但是好记性不如烂笔头,记下来供大家评鉴,有错改错,有善赞善,也是对于自己知识的一次梳理。

为什么要分清楚左值和右值?这是因为在理清楚左值和右值,合适为其设置适合的用法,能够有效减少资源开销。

但是,对于一些POD类型的资源,那就无所谓左值右值了,因为拷贝即移动,移动即拷贝。

接下来我以左值和右值的讨论依次简单讲解:左值和右值的概念,右值引用,移动语义,引用折叠,完美转发。明确左值和右值理清楚后,可以使用的主要用法。

:1. 开始看下面之前,需要注意的是!这些除了专业名词之外,基本都是基于个人理解去通俗诠释概括的,想直接看专业且全面的概念就找末尾的参考资料看。
2.以下有比较多的专业词汇,初学者建议慢慢看查询拓展。

概念

左值和右值的划分理解

左值(lvalue)和右值(rvalue)是C++11之前的概念,但是也通用到后面。
C++11及之后,划分为 泛左值(glvalue)、将亡值(xvalue,也称亡值,消亡值)和纯右值(prvalue)

左值(C++11之前):赋值运算“=”左边的变量
右值(C++11之前):赋值运算“=”右边的表达式左值(C++11及之后):非将亡值的泛左值,有地址的变量
右值(C++11及之后):纯右值或者将亡值,生命周期在表达式里。
int a = 15 + 29;
std::cout << &a;	// 0xeffc40
std::cout << &(15 + 29);	//error: Cannot take the address of an rvalue of type 'int'
std::cout << &"xzz";	//0xa16444

以简单的例子,这个a,承载类型的值,自身是有地址的,可以取地址值,这个就是左值。
15 + 29这个表达式的结果是纯右值,不能取地址值。

注:顺带一提,许多普通常量都是纯右值,但是字符串不是,是左值,因为普通常量都是可以用普通的机器码就可以表示其值,但是字符串无法合适表示,所以将其放置在常量区分配内存专门存放。

想必想了解左值和右值的人,估计都看过这个图:
在这里插入图片描述
或者是类似的,基本都是说将亡值泛左值右值的交集。

但是这其实是容易让人摸不着头脑的,但是本质角度上又是能说得过去的。

1. 将亡值被包含在右值这边,是因为其的    生命周期和右值是一样     的,都在一个表达式里面。
2. 将亡值被包含在泛左值这边,是因为其是      匿名对象,有地址,和左值是一样     的。

而上述也引申出了怎么判断将亡值。

将亡值:生命周期在一个表达式里,且是匿名对象有地址。

C++17的临时量实质化也是将亡值。

.

右值引用

右值引用T &&),顾名思义是引用右值的,无论是纯右值还是将亡值

右值引用是C++11引入的,值得注意的是右值引用的变量是个左值

因为其是完全符合左值定义的,众所周知,引用本质上是一种特殊的指针,可以这么认为,指针指向的值是右值,但是指针本身并不是右值。

所以你如果想右值引用 右值引用的变量 这样是不行的:

int &&a = 5;	// 编译正常,可以随意右值引用纯右值
int &&b = a;   	// 编译错误

右值引用的目的是延长将亡值的生命周期,减少资源开销,或者是为了移动语义服务,使其进行资源转移。

struct AA {};
AA createAA() {return AA();
}
int main() {AA &&a = createAA(); 
}

右值引用AA &&a接纳了本来表达式结束就要释放掉资源的匿名对象AA()

并可以任意更改匿名对象的资源。

常量左值引用与右值引用

在C++11之前,负责右值引用(T &&)功能的是常量左值引用(const T &),只不过和右值引用相比,常量左值引用无法修改其值,且只能用于拷贝语义不能用以移动语义
在这里插入图片描述
在这里插入图片描述
可以看出来,常量左值引用右值引用做的事情是一样的。

顺带一提,不建议用右值引用去引用POD类型的纯右值,因为纯右值要想被右值引用,就得先压栈地址,才能给其引用。

从开销上看,不如直接普通的赋值
在这里插入图片描述
在这里插入图片描述
就算单纯只看条数,右值引用用了3条,普通赋值才用了1条,开销一目了然。

.

移动语义

移动语义(Move Semantics)是 C++11 引入的一项重要特性,它使得实例对象的资源不通过拷贝的方式进行转移(除了POD类型)。

移动语义具体化其实就是移动构造函数。

struct Resource { ... }class XZZ 
{
public:...构造或者其他的实例化资源...移动构造函数XZZ(XZZ &&value) {this.m_resource = value.m_resource;value.m_resource = nullptr;}/// 移动赋值函数XZZ &operator =(XZZ &&value) {this.m_resource = value.m_resource;value.m_resource = nullptr;}...
private:Resource *m_resource = nullptr;
}

上面是个简单的例子,主要是为了理解移动是怎么来移动资源的。

如果m_resource不是指针,也可以通过使用std::move强行将value.m_resource转成右值来触发this.m_resource的移动构造,使得两个m_resource的资源进行移动达到同样的效果。

_EXPORT_STD template <class _Ty>
_NODISCARD _MSVC_INTRINSIC constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept {return static_cast<remove_reference_t<_Ty>&&>(_Arg);
}

std::move的效果便是强制将传进来的参数转成右值,一般可以将已经右值引用的变量或者将要释放的类型转成右值(将亡值),实现移动语义的功能。

再次提醒,如果资源是POD类型的,那用移动语义其实没有意义,因为移动就是拷贝,拷贝就是移动。

另外移动构造什么情况下可以编辑器会提供默认移动构造,什么情况下会弃置默认移动构造只能自己写的,这些内容不在本节重点,感兴趣可自行查看。
.

引用折叠

说回右值引用的类型,左值引用右值引用,或者右值引用左值引用,那到底是左值引用还是右值引用呢?

C++11中引入引用折叠规则(reference collapsing),通过模板或 typedef 中的类型操作可以构成引用的引用,此时适用引用折叠规则:右值引用的右值引用折叠成右值引用,所有其他组合均折叠成左值引用

废话不多说:
C++ 11新特性解析与应用
简单通俗来说,只有右值引用本身,和叠加两次的右值引用,类型才是右值引用类型,否则,含至少一个引用&的都是左值引用

不能直接声明一个超过两个&的类型

int a = 10;
int &&& b = a;	// error: 'b' declared as a reference to a reference

但是如果通过using或者typedef间接声明就可以了

typedef int& intR;
using intRe = int&;int a = 10;
intR && b = a;		// 等同于 int &b = a
intRe && c = a;		// 等同于 int &c = a

有了引用折叠,就可以好好使用类型擦除完美转发参数类型给别的函数或者类。
.

完美转发

所谓完美转发(prefect forwarding),是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。 ——《C++ 11新特性解析与应用》

完美转发关键点在于:

  1. 函数模板
  2. 函数模板参数类型是 类型&&
  3. 要接收函数模板参数的函数/类,实参用std::forward包装一下
template <typename _Ty, typename... _Type>
_Ty *createClass(_Type&&... args) {return new _Ty(std::forward(args)...);
}

这是个没什么实质意义的模板函数,仅是为了举例。

为什么要用std::forward

是因为右值引用args本身是左值,传进来本身如果是个右值的话,结果给到接收函数是个左值,那就不是“完美”转发了。

_EXPORT_STD template <class _Ty>
_NODISCARD _MSVC_INTRINSIC constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept {return static_cast<_Ty&&>(_Arg);
}_EXPORT_STD template <class _Ty>
_NODISCARD _MSVC_INTRINSIC constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept {static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");return static_cast<_Ty&&>(_Arg);
}

所以需要转成右值的类型,而如果是左值的话,因为函数重载引用折叠的缘故,即使通过std::forward也是转成左值类型。

参考资料

《C++ 11新特性解析与应用》
《C/C++ 参考文档》

http://www.yayakq.cn/news/896371/

相关文章:

  • 有哪个网站可以学做早餐吃的克州建设工程信息网
  • 网站建设朋友圈素材个人又什么办法做企业网站
  • 网站建设项目管理基本要求网站建设价格受哪些影响
  • 百度收录申请入口做搜狗手机网站优化
  • 关于asp sql网站开发的书籍网站标签设置
  • 网站域名需要交费吗企业展厅效果图
  • 网站架构设计师岗位要求wordpress 帕兰映像 安装教程 wordpress
  • 三维建设项目管理网站安卓模仿网站开发详细教程
  • 广州五羊建设官方网站北京做手机网站的公司
  • 贵州省城乡与建设厅网站wordpress 跳转到首页
  • 社区网站制作网站中的文字滑动怎么做的
  • 如何在网站上做背景图片怎么做优秀产品设计案例
  • 企业网站建设实训指导书网站和网页的设计方法
  • 企业网站开发框架wordpress 评论回信
  • 网站标题logo怎么做做门户网站的公司
  • 中国万网网站建设服务自媒体营销推广
  • 网站建设地域名凡科送审平台官网
  • 迪庆企业网站建设各行业网站建设方案书
  • 花都手机网站建设seo是什么职务
  • 鞍山百度做网站杭州网站建设杭州沃迩夫
  • 东莞招聘网官方网站微信推广朋友圈广告
  • 网站浏览排名微信公众号开发步骤
  • 东台做网站哪家便宜无忧seo
  • 网站建设的风险识别注册网站应注意事项
  • 选服务好的网站建设公上海设计招聘网站
  • 承德建设局网站一站式建站价格
  • 北京 网站设计公司门户wordpress主题下载
  • 什么网站做微信公众账号网站设计开户
  • 企业型网站有哪些特点网站域名备案证书下载
  • 如何网站关键词优化设计公司网站建设