C++0x右值、move、forward、引用退化

原创 2012年03月29日 19:44:43

昨天又学习了下右值、move和forward。记录一下学习到的东西:

1、引用退化

左值引用有传染性。左值引用的右值引用或右值引用的左值引用结果都是左值引用,即:

string& &&和string&& &都等于string&

string & & 等于string &

string && &&等于string &&

2、左值和右值是表达式的属性

即存在这个情况:某个变量的类型是右值引用,但变量自己构成的表达式却是左值


3、具名的左值引用和右值引用都是左值,不具名的右值引用是右值

因为有名字的变量,不管是左值还是右值,在你没有明确声明的情况下,默认不会立即销毁,因此不能当右值看待


4、move

不管左值引用还是右值引用,通过move后都换成右值引用


5、forward

std::forward<T>(x)

如果T是string,那么返回string&&;如果T是string&,那么返回string&。返回类型和x类型无关

那为什么叫完美转发呢?和x是左值引用还是右值引用都没有关系!!

关键在于这个T不是固定的,而是由编译器从函数参数上类型推导出来的。

template <typename T>
T&& func(T&& x)
{
    return std::forward<T>(x);
}

当用string&调用func时,T的类型推导为string&。由于引用退化,T&&等效于string&,因此返回值也是左值string&。

当用string&&调用func时,T的类型推导为string。因此返回值就是string&&。

从而做到了完美转发。

因此foward的完美转发一定要和模板参数自动推导关联起来使用,单独forward自己是没法完美转发的。


6、使用右值作为函数参数对传统函数进行优化

一般对形如:func(const X& data)的函数进行重载优化:

func(X&& data)

当实参是X&、const X&、const X&&时,调用老的函数。而当实参是X&&时,调用新的函数以获得性能上的提升。


7、默认类型转换

Type&& 可以默认转为Type&、const Type&、const Type&&。因为它的约束是最强的。它的约束包含:

a) 指向一个合法的对象

b) 可以修改

c) 该对象马上将销毁,可以偷窍其数据

而Type&只包含a)、b)两个约束 

const Type&&可以默认转为const Type&

Type&只能默认转换为const Type&。如需把它转成Type&&,可以使用std::move

const Type&不能转换成其它三个类型


8、const Type&&没啥存在的意义

马上都要销毁了,还不让人修改,图啥呢?







C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

C++11, 右值引用,move, forward
  • xiaolewennofollow
  • xiaolewennofollow
  • 2016年09月16日 23:59
  • 1225

C++11尝鲜:右值引用和转发型引用

解决移动语义及完美转发问题
  • zwvista
  • zwvista
  • 2013年10月05日 19:52
  • 10253

C++11:深入理解右值引用,move语义和完美转发

乍看起来,move语义使得你可以用廉价的move赋值替代昂贵的copy赋值,完美转发使得你可以将传来的任意参数转发给 其他函数,而右值引用使得move语义和完美转发成为可能。然而,慢慢地你发现这不那么...
  • booirror
  • booirror
  • 2015年04月15日 12:45
  • 28659

C++11学习笔记:std::move和std::forward源码分析

std::move和std::forward是C++0x中新增的标准库函数,分别用于实现移动语义和完美转发。 下面让我们分析一下这两个函数在gcc4.6中的具体实现。 预备知识 引用折叠...
  • xie1xiao1jun
  • xie1xiao1jun
  • 2014年11月25日 18:09
  • 9223

条款23:理解std::move和std::forward

通过了解std::move和std::forward不做什么来理解它们很有用。std::move不移动任何东西,std::forward也不转移任何东西。在运行时(runtime),他们什么都不做,一...
  • coolmeme
  • coolmeme
  • 2015年03月20日 17:12
  • 15113

c++11 函数内部返回对象使用move语义的最佳实践

一句话,直接返回即可,不用任何变化。当启动了c++11选项后,通过函数返回代码没有发生任何变化,但是已经使用了move语义,而不需要之前的NRVO编译器优化技术。下面是stackoverflow上的一...
  • sheismylife
  • sheismylife
  • 2015年04月12日 21:28
  • 2931

深入浅出C++11(3) -- 右值引用和move语义

右值引用 什么是lvalue, 什么是rvalue? lvalue: 具有存储性质的对象,即lvalue对象,是指要实际占用内存空间、有内存地址的那些实体对象,例如:变量(variables)、函...
  • liqinghua1653
  • liqinghua1653
  • 2013年10月04日 20:49
  • 6619

移动语义(move semantic)和完美转发(perfect forward)

https://codinfox.github.io/dev/2014/06/03/move-semantic-perfect-forward/   新标准重新定义了lvalue和rvalue,并...
  • suchto
  • suchto
  • 2017年02月09日 15:42
  • 523

C++0x,std::move和std::forward解析

深入解析std::move and std::forward
  • zjq2008wd
  • zjq2008wd
  • 2015年03月04日 14:41
  • 440

c++ const 成员函数 & 临时变量 & 右值引用 & move

const 成员函数尊重原作,部分转自http://blog.csdn.net/lihao21/article/details/8634876我们知道,在C++中,若一个变量声明为const类型,则试...
  • GW569453350game
  • GW569453350game
  • 2015年07月27日 09:41
  • 3547
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++0x右值、move、forward、引用退化
举报原因:
原因补充:

(最多只允许输入30个字)