当前位置:   article > 正文

关于左值,右值(移动语法 &&和std::move)_&& 参数 std::move

&& 参数 std::move

首先是移动语法。

int&&和int&类型的主要区别有以下几点:

  1. 引用类别
  • int&是左值引用,只能绑定到左值上,即具名对象。

  • int&&是右值引用,可以绑定到右值和左值。

  1. 绑定对象
  • int&必须绑定到一个已经存在的对象(左值)上。

  • int&&可以绑定到一个临时对象(右值)上。

  1. 移动语义
  • int&不支持移动语义,传值时总是复制对象。

  • int&&支持移动语义,传值可以直接移动而不是复制对象。

  1. 传参方式
  • int&常用于引用传参,以避免复制对象。

  • int&&一般用于传值的场景,实现高效移动操作。

  1. 对象生命周期
  • int&绑定的对象在绑定作用域外仍然有效。

  • int&&绑定的临时对象生命周期结束被销毁。

所以总结来说:

int&是左值引用,int&&是右值引用。
int&用于引用传参,int&&用于实现移动语义的传值操作。
int&&支持移动临时对象的资源。

两者在语义和使用场景上有明显差异。

int&&用法举例

“int&&支持移动语义,传值可以直接移动而不是复制对象”,具体来说指:

  • 对于一个临时对象(右值),如果将它直接传值传递给一个函数,会触发其拷贝构造函数进行值拷贝。

  • 而如果参数声明为右值引用int&&,就可以利用C++11新增的移动语义。

  • 移动语义允许直接移动临时对象的内容,而不是复制其值。这避免了不必要的拷贝操作。

举个例子:

void func(int value){
  // value被值拷贝 
}

int main(){
  int temp = 10;
  func(temp); // temp被拷贝
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

即便temp是一个临时对象,它也会被拷贝一份。

而使用右值引用:

void func(int&& value){
  // value移动而非拷贝
}

func(10); // 直接移动10而非拷贝
  • 1
  • 2
  • 3
  • 4
  • 5

这里10是一个临时对象,通过右值引用就可以直接移动其值到func,而不是复制一个临时副本。

所以总体来说,int&&能利用C++11移动语义特性,直接移动临时对象内存而不是值拷贝,从而提高效率。

std::move()

传入

如果func函数的参数是变量a,而不是一个临时数值,那么是否需要加std::move取决于以下情况:

  • 如果a是泛指的变量,既可能是右值也可能是左值,此时需要加std::move:
int a = 10;
func(std::move(a)); 
  • 1
  • 2

std::move将a转换为右值引用,以使用移动语义传递。

  • 如果明确声明a是左值,如常量引用,此时不需要std::move:
int a = 10;
const int& ref = a;
func(ref);
  • 1
  • 2
  • 3

ref是一个左值引用,直接传递可以使用移动语义。

  • 如果a是函数参数而不是变量,也不需要std::move:
void bar(int a) {
  func(a); 
}
  • 1
  • 2
  • 3

参数a已经是右值,直接使用移动语义。

总之:

  • 如果参数本身就是右值,无需std::move。

  • 如果参数可能是左值,使用std::move强制转换为右值传递。

  • 如果参数是常量引用/引用类型的左值,也无需std::move。

所以是否需要std::move,关键看参数本身是左值还是右值。

传出

如果在func函数中,想将右值引用参数value的值赋给一个变量b,此时是否需要std::move如下:

  • 如果b是右值引用类型(int&& b),则不需要std::move:
void func(int&& value){
  int&& b = value; //直接赋值,实现移动语义
}
  • 1
  • 2
  • 3
  • 如果b是普通变量(int b),这里需要std::move:
void func(int&& value){
  int b = std::move(value); //b是左值,value右值,需要std::move
}
  • 1
  • 2
  • 3

这是因为:

  • value作为参数是右值引用,表示可以直接移动其值。

  • 但赋值给普通变量b时,b是左值,value作为右值无法直接访问其内存。

  • 使用std::move可以将value从右值引用转换为纯右值,使得其值可以被移动给左值b。

所以总结来说:

  • 如果目标是右值引用,不需要std::move直接赋值即可移动;

  • 如果目标是普通变量(左值),需要std::move将源转换为右值以支持移动操作。

这是因为std::move的作用就是值类别转换,支持值之间的移动语义传递。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/640023
推荐阅读
相关标签
  

闽ICP备14008679号