C++ 右值引用与移动操作

右值引用和移动操作是C++11提出的新概念,通过这些操作,可以降低拷贝操作带来的消耗。先来简单介绍一下左值和右值。

左值一般指的是一个对象,或者说是一个持久的值,例如赋值的返回值、下标操作、解引用以及前置递增等。

右值是一个短暂的值,比如一个表达式的求值结果、函数返回值以及一个字面值等。

 

为了区分,把一般的引用称为左值引用,必须绑定到右值的引用称为右值引用,以&&表示。右值引用有这两个特性:

右值引用只能绑定到临时对象,所引用的对象将要被销毁,并且没有其他用户

这也意味着,我们可以自由地接管引用对象的资源。

通常一个变量可以认为是左值,也即是一个对象。那么如何获得右值呢?可以显示转换为对应的右值引用,也可以调用标准库函数std::move()。

move()承诺了我们不再使用移后源,不保证移后源的状态和值。

实际上,移动操作窃取了对象资源的控制权,从而避免了不必要的拷贝。

int i = 1;
int&& rr = std::move(i);

移后源对象必须是可以析构的,并且要保证对象依然有效,可以被赋予新值,但是不保证移后源对象中留下的值。

事实上,单纯调用std::move()并不会对对象进行改变,只有另外一个对象接管了资源后,移动才真正完成。

 

<<C++ primer>>在模板操作中详细解释了std::move的具体实现和工作。

template<typename T> typename remove_reference<T>::type&& move(T&& t)
{
    return static_cast<typename remove_reference<T>::type&&> (t);
}

move的参数是一个T&&,而任何有名字的参数实际上都是左值。也就是说,这个参数可以和任何类型的参数匹配,可以传左值也可以传右值。

posted @ 2017-09-12 20:59  luStar  阅读(2972)  评论(0编辑  收藏  举报