左值、右值、右值引用与move()、forward()

1、左值(lvalue):可以进行取地址(&)运算的是左值。或者有时候可以理解为 既能够出现在等号左边也能出现在等号右边的变量(或表达式)。

2、右值(rvalue):不可以进行取地址(&)运算的是右值。或者有时候可以理解为 只能出现在等号右边的变量(或表达式)。

  • 常见的右值有 字面量、函数返回的临时对象,匿名对象等。
  • 以上判断一个对象是左值还是右值并不完全正确。
const int c_a = 10;        //左值,但是不能被赋值,也就不能出现在 = 左边
//字符串字面值,可以取地址,是左值,但是也不能位于等号左边
&("我只左值");                //正确
//有时候右值是可以位于等号左边的
string s1, s2;
s1 + s2 = "它是右值但是能被赋值“;

3、右值引用(rvalue referrence):是C++11引入的一个新类型。右值有一下特性:

  • 可以直接绑定到右值。
  • 不能直接绑定到左值。
  • 本身是一个左值。可以进行 &运算。
  • 右值能被 const 类型的引用绑定。
  • 可以使用move()将左值绑定到右值引用上。
int a = 10;
int &b = a;
int &&c = a * 10;       //右值引用直接绑定右值
const int &d = a * 20;    //右值引用绑定到const型引用int &&e = a;          //错误。无法将右值引用绑定到左值
int *f = &e;                 //右值引用可以进行&运算
int &&g = move(a);        //使用move()将左值绑定到右值引用上
  • 可以使用move()将左值绑定到右值引用上。
  • move调用告诉编译器:我们有一个左值,但我们希望像一个右值一样处理它。我们必须认识到,调用move就意味着承诺:除了对rr1赋值或销毁它外,我们将不再使用它在调用move后,我们不能对移后源对象的值做任何假设。我们可以销毁一个移后源对象,也可以赋予它新值,但是不能使用一个移后源对象的值。
  • std::forward()。 函数原型:std::forward<T>(u) 有两个参数:T 与 u。当T为左值引用类型时,u将被转换为T类型的左值,否则u将被转换为T类型右值。如此定义std::forward是为了在使用右值引用参数的函数模板中解决参数的完美转发问题。
//forward
template<typename _Tp>
  inline _Tp&&
  forward(typename std::remove_reference<_Tp>::type& __t)
  { return static_cast<_Tp&&>(__t); }  

int a = 10;
int &b = forward<int &>(a);    //返回左值引用
int &&c = forward<int &&>(a);   //返回右值引用
int &&d = forward<int>(a);     //返回右值引用

原文地址:https://www.cnblogs.com/peformer/p/9087360.html

时间: 2024-08-29 09:50:11

左值、右值、右值引用与move()、forward()的相关文章

C++11中的右值引用和move函数

新版的C++标准库出现了很多C++11的新特性,刚开始接触确实很费劲,特别是右值引用和move函数这种基于效率的考虑损失了语言的简单直接的特性,废话不多说,先看右值引用. C++中根据const和non_const,lvalue和rvalue可分为四类对象  non_const          const lvalue  非常量左值         常量左值 rvalue  非常量右值         常量左值 如果使用C++03标准,函数的参数选择const reference(常量引用),

[转载]如何在C++03中模拟C++11的右值引用std::move特性

本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalue reference,右值引用. 引入它的一个非常重要的原因是因为在 C++ 中,常常右值,通俗地讲"在等号右边的"临时变量或者临时对象,我们是无法得到它的修改权限的. 由于类的构造和析构机制,往往产生的临时变量或临时对象的拷贝构造及析构,会带来不少的时间.资源消耗. 也同样由于这样的限

深入右值引用,move语义和完美转发

深入右值引用,move语义和完美转发 转载请注明:http://blog.csdn.net/booirror/article/details/45057689 乍看起来,move语义使得你可以用廉价的move赋值替代昂贵的copy赋值,完美转发使得你可以将传来的任意参数转发给 其他函数,而右值引用使得move语义和完美转发成为可能.然而,慢慢地你发现这不那么简单,你发现std::move并没有move任何东西,完美转发也并不完美,而T&&也不一定就是右值引用-- move语义 最原始的左值

c# 值类型与引用类型 值传递与引用传递

值类型与引用类型: 值类型 :1.值类型大小固定.存储在栈上.  2.不能继承,只能实现接口 3.派生自valuetype int double char float byte bool enum struct decimal 引用类型:1.在栈上存储了一个地址实际存储在堆中,大小不固定. 2.数组.类.接口.委托 string 数组 类 接口 委托 值传递与引用传递: 值类型按值传递.值类型按引用传递.引用类型按值传递.引用类型按引用传递. 值传递:默认传递都是值传递 ,把栈中内容拷贝一份引用

为什么 Java 只有值传递,但 C# 既有值传递,又有引用传递,这种语言设计有哪些好处?

为什么 Java 只有值传递,但 C# 既有值传递,又有引用传递,这种语言设计有哪些好处? http://www.zhihu.com/question/20628016 Java值传递的终极解释 http://developer.51cto.com/art/201103/251163.htm

java只有值传递,不存在引用传递

今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? 我毫无疑问的回答:“引用传递!”,并且还觉得自己对java的这一特性很是熟悉! 结果发现,我错了! 答案是: 值传递!Java中只有按值传递,没有按引用传递! 回家后我就迫不及待地查询了这个问题,觉得自己对java这么基础的问题都搞错实在太丢人! 综合网上的描述,我大概了解了是怎么回事,现在整理如下,如有不对之处望大神提出! 先来看一个作为程序员都熟悉的值传递

span文字在左背景图片在右

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style type="text/css">span {     background-image:url(http://a3.qpic.cn/psb?/V11OXL2y3vDNOK/BLjgWL6kfs*3sZIUVjubWPHQWxn

R_Studio(癌症)以等宽类别值、自定义类别值、等频类别值(分为5类)

对"癌症.csv"中的肾细胞癌组织内微血管数进行连续属性的离散化处理 增加"微血管数分类1"属性,取值为等宽类别值(分为5类),增加"微血管数分类2"属性,取值为自定义类别值(0~40,41~60,61~120,121~150,151~200,201~250),增加"微血管数分类3"属性,取值为等频类别值(分为5类) setwd('D:\\data') list.files() #读取数据 dat=read.csv(file=

error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2

使用VS2013版本引用外部的lib进行编译时候提示: 错误 25 error LNK2038: 检测到"_ITERATOR_DEBUG_LEVEL"的不匹配项:  值"0"不匹配值"2"(jrtplibSend.obj 中) F:\jrtplibProjects\jrtplibSend\jrtplibSend\jrtplib.lib(rtpudpv6transmitter.obj) jrtplibSend 产生这个问题的原因是当前工程是Debu