C++中的左值和右值
来源:互联网 发布:淘宝鳄鱼皮真假鉴别 编辑:程序博客网 时间:2024/06/08 02:39
左值和右值的定义
在C++中,可以放到赋值操作符=左边的是左值,可以放到赋值操作符右边的是右值。有些变量既可以当左值又可以当右值。进一步来讲,左值为Lvalue,其实L代表Location,表示在内存中可以寻址,可以给它赋值(常量const类型也可以寻址,但是不能赋值),Rvalue中的R代表Read,就是可以知道它的值。例如:
int a=3;
a在内存中有地址,而3没有,但是可以read到它的值。
3=4;
这个是错误的,因为3的内存中没有地址,不能当作左值。
下面这个语句不容易出错
a++=3;
这个语句编译通不过的,原因在于a++是先使用a的值,再给a加1。实现如下:
- {
- int tmp=a;
- a=a+1;
- return tmp;
- }
{ int tmp=a; a=a+1; return tmp;}++a是右值。
++a=3;
这个是正确的,++a的实现如下:
- {
- a=a+1;
- return &a;
- }
{ a=a+1; return &a;}显然++a的效率高。
左值符号&和右值符号&&
左值的声明符号为&,右值的声明符号为&&。在C++中,临时对象不能作为左值,但是可以作为常量引用const &
- #include<iostream>
- void print_lvalue(int& i)//左值
- {
- std::cout << ”Lvalue:” << i << std::endl;
- }
- void print_rvalue(int&& i)//右值
- {
- std::cout << ”Rvalue:” << i << std::endl;
- }
- int main()
- {
- int i = 0;
- print_lvalue(i);
- print_rvalue(1);
- //print_lvalue(1)会出错
- //print_lvalue(const int& i)可以使用print_lvalue(1)
- return 0;
- }
#include<iostream>void print_lvalue(int& i)//左值{ std::cout << "Lvalue:" << i << std::endl;}void print_rvalue(int&& i)//右值{ std::cout << "Rvalue:" << i << std::endl;}int main(){ int i = 0; print_lvalue(i); print_rvalue(1); //print_lvalue(1)会出错 //print_lvalue(const int& i)可以使用print_lvalue(1) return 0;}
C++11中的move
有时候我们希望把左值当作右值来使用,例如一个变量的值,不再使用了,希望把它的值转移出去,C++11中的std::move就为我们提供了将左值引用转为右值引用的方法。
- #include<iostream>
- void print_value(int& i)//左值
- {
- std::cout << ”Lvalue:” << i << std::endl;
- }
- void print_value(int&& i)//右值
- {
- std::cout << ”Rvalue:” << i << std::endl;
- }
- int main()
- {
- int i = 10;
- print_value(i);
- print_value(std::move(i));
- return 0;
- }
#include<iostream>void print_value(int& i)//左值{ std::cout << "Lvalue:" << i << std::endl;}void print_value(int&& i)//右值{ std::cout << "Rvalue:" << i << std::endl;}int main(){ int i = 10; print_value(i); print_value(std::move(i)); return 0;}
最长用的交换函数
- void swap(T& a, T& b)
- {
- T tmp = std::move(a);
- a = std::move(b);
- b = std::move(tmp);
- }
void swap(T& a, T& b){ T tmp = std::move(a); a = std::move(b); b = std::move(tmp);}避免了3次拷贝。
move的本质,只是将参数转换为右值引用,并没有移动什么。因此要实现类关于右值得构造函数和复制操作符。move实现如下:
- template <typename T>
- decltype (auto) move(T&& param){
- using ReturnType = remove_reference_t<T>&&;
- return static_cast<ReturnType>(param);
- }
template <typename T>decltype (auto) move(T&& param){ using ReturnType = remove_reference_t<T>&&; return static_cast<ReturnType>(param);}
精确值传递
std::forward主要用于模板编程中,值传递的问题。可以推测参数是左值引用还是右值引用,精确传递值。参考这里:
http://blog.csdn.net/zwvista/article/details/6848582
阅读全文
0 0
- c/c++中的lvaues(左值)和rvalues(右值)
- C语言中的左值和右值
- 转载:C语言中的左值和右值
- c语言中的“左值”和“右值”
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- c++中的左值和右值
- c++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- C++中的左值和右值
- c++中的左值和右值
- nginx + php 修改php.ini生效
- 游戏编程之DirectX的修炼:二(创建属于自己的windows窗口程序:下)
- 20170831美团笔试:长度为n的数组中最长的和为K的倍数的连续子数组
- Swift 中的结构体 (Struct)
- Tyvj1022
- C++中的左值和右值
- 千寻穗C语言学习日记8.31
- 从二叉搜索树的第k个节点问题看递归如何返回普通变量和对象
- 内核驱动程序完整性校验的原理分析
- js 数组基础
- Java编程思想读书笔记——一切都是对象
- 如何用JAVA语句创建一个表
- "undefined reference to" 问题解决方法
- 如何 面对自己的负面情绪-刘轩