std::move()和std::forward()

Posted 你好呵呵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了std::move()和std::forward()相关的知识,希望对你有一定的参考价值。

  std::move(t)负责将t的类型转换为右值引用,这种功能很有用,可以用在swap中,也可以用来解决完美转发。

  std::move()的源码如下

template<class _Ty> inline
    _CONST_FUN typename remove_reference<_Ty>::type&&
        move(_Ty&& _Arg) _NOEXCEPT
    {    // forward _Arg as movable
    return (static_cast<typename remove_reference<_Ty>::type&&>(_Arg));
    }

先说一下实参为左值的情况。

按理来说左值是无法匹配右值形参的,但是c++为了move这个基础设施开了两个例外。

第一个例外是当形参为右值引用,实参为左值时,编译器推断模板类型参数为实参的左值引用类型。比如

template<typename T> void f(T&&);
int i;
f(i);

这样编译器推断T为int &类型。

但是按之前的规定,我们并不能直接定义引用的引用,于是有了第二个例外——引用折叠。

引用折叠的规则如下:

& & == & && == && & == &

&& && == &&

有了这两个例外,move就可以接受任何类型的实参,从而获得一个右值引用。

std::forward()源码如下:

template<class _Ty> inline
    _CONST_FUN _Ty&& forward(
        typename remove_reference<_Ty>::type& _Arg) _NOEXCEPT
    {    // forward an lvalue as either an lvalue or an rvalue
    return (static_cast<_Ty&&>(_Arg));
    }

forward()必须通过显式模板实参来调用,并返回该显示模板实参的右值引用。比如std::forward<T>的返回类型为T&&。

forward的使用通常如下:

template<class T>
void fwd(T&& t)
{
    foo(std::forward<T>(t));
}

若实参为左值,根据引用折叠,T为左值引用,则执行foo()的实参为左值引用;若实参为右值,则执行foo()的实参为右值引用,符合完美转发。

以上是关于std::move()和std::forward()的主要内容,如果未能解决你的问题,请参考以下文章

std :: move和std :: forward之间有什么区别

std::move和std::forward

std::move与std::forward

std::move与std::forward

std::move与std::forward

C++11的右值引用移动语义(std::move)和完美转发(std::forward)详解