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++0x,std::move和std::forward解析

深入解析std::move and std::forward

VC10中的C++0x特性 Part 2 (1):右值引用

----------------------------------------------------------------------------------------------------...

C++0x的右值和右值引用

这是我对自己最近学习c++0x中,关于右值和右值引用的一个总结。 这篇博文的原始地址在http://storming.github.io/libllpp/。 我很想把自己的理解分享给大家,...

C++0x的右值和右值引用

这篇博文的原始地址在http://storming.github.io/libllpp/。 我很想把自己的理解分享给大家,并且和大家一起讨论。这篇博文的内容只是我对这个概念的理解,并不是太严谨。...

Item 25: 对右值引用使用std::move,对universal引用则使用std::forward

本文翻译自《effective modern C++》,由于水平有限,故无法保证翻译完全正确,欢迎指出错误。谢谢! 右值引用只能绑定那些有资格被move的对象上去。如果你有一个右值引用类型的参数,你就...
  • boydfd
  • boydfd
  • 2016年03月12日 14:28
  • 956

Effective Modern C++ 条款25 对右值引用使用std::move,对通用引用使用std::forward

Effective Modern C++ 条款25

条款25:对右值引用使用std::move,对统一引用使用std::forward

右值引用仅仅绑定到那些准备移动的候选对象上。假如你有个右值引用参数,你应该知道它绑定的对象可以被移动: class Widget { public:     Widget(Widget&& rhs);...

vc2012的c++0x特性对std::move的支持测试

最近对我的开源库st_asio_wrapper(基于boost.asio的c/s框架)做了个详细的检查,主要是看看在防止内存拷贝上是否达到了我的预期,vc2012的结果似乎不满意(相对于gcc4.7来...

初窥c++11:从move语义到右值引用

技术人员往往比较傲慢,写c语言的鄙视c++,写c++的鄙视Java,写Java的鄙视c#,要是程序员吵起来怎么办,一个流行的办法就是去github约架,比赛写tokenizer和grammar ana...

C++11特性:右值引用与move语义

右值引用右值引用是C++11中的一个重要特性,它的出现解决了很多C++历史遗留问题。其总结来说可以说是解决了栈中对象的所有权的转移问题。首先右值是从C语言设计时就有的概念。不严格的来说,左值对应变量的...
  • MBuger
  • MBuger
  • 2017年04月26日 22:42
  • 231
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++0x右值、move、forward、引用退化
举报原因:
原因补充:

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