ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ 中的左值与右值

2021-01-04 21:29:37  阅读:150  来源: 互联网

标签:右值 C++ 万能 左值 param 引用 &&


C++ 左值与右值

C++ 非常注重运行效率,而 C++11 被最广泛接受的可能就是移动语义,而移动语义的基础在于区别左值表达式和右值表达式,因为一个对象是右值意味着能够对其实施移动语义,左值不可以。这里对左值右值的理解不能再以变量在表达式的左边还是右边来判定了。
判断一个表达式是左值还是右值概括来说:

左值表达式是可以对其取地址的 (形参总是左值)
右值表达式不可以(临时对象)

如果只是看明白了上面两句话就觉得已经具备足够的能力来分辨了,那可能还是有点难度的。

int a;  // a 可以对其取地址,所以 a 是左值
++a;  // ++a,是对 a 对象直接加1,并返回 a,依旧可以对其取地址, ++a 是左值
a++;  // a++ 是对 a 拷贝的临时对象上加1,然后返回这个拷贝的临时对象,临时对象无法取地址,a++ 是右值

因为右值一般都是临时对象的形式存在,它是没有名字的,所以想找到它只能通过引用的方式,而这就引入了 C++ 中右值引用(T&&)的概念。

右值引用与万能引用

这两者概念的区别主要在于右值引用与万能引用具有相同的形式:T&&
右值引用仅仅会绑定到右值上。而万能引用则可以绑定到带/不带 const/volatile 修饰词的,或者同时带有 const和volatile 的左值/右值对象上。
万能引用主要在一下两个场景出现:

// 模板参数的形参
template<typename T>
void f(T&& param);  // param 是个万能引用

// auto 声明
auto&& v2 = v1;  // v2 是个万能引用

上述两个场景都在于它们涉及类型推导
不涉及到类型推导的就是右值引用了:

void f(int&& param); // 右值引用
int&& v1 = 2; // 右值引用
template<typename T> void f(std::vector<T>&& param); // 右值引用,因为一定是 vector 形式的
template<typename T> void f(T&& param); // 万能引用
template<typename T> void f(const T&& param); // const 存在使 param 是右值引用

当是右值引用时,我们不能将左值传递给它:

template<typename T> 
void f(std::vector<T>&& param); // 右值引用

std::vector<int> v;
f(v); //编译器会报错,不能把右值引用绑定到左值上

万能引用的初始化是必须的,其初始化会决定它是左值还是右值引用。

以上在 vector 的 push_back 的源码中就使用的 T&& 形式,vector 的类型确定下来,T 的类型就确定下来了,所以只是右值引用,而 emplace_back 就是存在类型推导,是万能引用。

标签:右值,C++,万能,左值,param,引用,&&
来源: https://blog.csdn.net/Chris_zhangrx/article/details/112200174

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有