zoukankan      html  css  js  c++  java
  • 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()的实参为右值引用,符合完美转发。

  • 相关阅读:
    vue强制更新$forceUpdate()
    js数组拼接成字符串,去除最后一个逗号
    JavaScript数组遍历:for、foreach、for in、for of、、().each的区别
    json.stringify()的妙用,json.stringify()与json.parse()的区别
    第四次博客作业-结对项目
    于达——第九次作业
    于达——第八次作业
    软件工程第三次作业——关于软件质量保障初探
    于达——第七次作业
    于达——第六次作业
  • 原文地址:https://www.cnblogs.com/tonychen-tobeTopCoder/p/5274542.html
Copyright © 2011-2022 走看看