C++中的左值和右值

xiaoxiao2021-02-28  93

左值和右值的定义

在C++中,可以放到赋值操作符=左边的是左值,可以放到赋值操作符右边的是右值。有些变量既可以当左值又可以当右值。进一步来讲,左值为Lvalue,其实L代表Location,表示在内存中可以寻址,可以给它赋值(常量const类型也可以寻址,但是不能赋值),Rvalue中的R代表Read,就是可以知道它的值。例如: int a=3; a在内存中有地址,而3没有,但是可以read到它的值。 3=4; 这个是错误的,因为3的内存中没有地址,不能当作左值。 下面这个语句不容易出错 a++=3; 这个语句编译通不过的,原因在于a++是先使用a的值,再给a加1。实现如下: [cpp] view plain copy print ? {      int tmp=a;      a=a+1;      return tmp;  }   { int tmp=a; a=a+1; return tmp; } ++a是右值。 ++a=3; 这个是正确的,++a的实现如下: [cpp] view plain copy print ? {      a=a+1;      return &a;  }   { a=a+1; return &a; }显然++a的效率高。

左值符号&和右值符号&&

左值的声明符号为&,右值的声明符号为&&。在C++中,临时对象不能作为左值,但是可以作为常量引用const & [cpp] view plain copy print ? #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就为我们提供了将左值引用转为右值引用的方法。 [cpp] view plain copy print ? #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; } 最长用的交换函数 [cpp] view plain copy print ? 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实现如下: [cpp] view plain copy print ? 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
转载请注明原文地址: https://www.6miu.com/read-59796.html

最新回复(0)