• c++11 perfect forwarding


    完美转发是c++11 引入右值引用之后,在template 中的延伸. 顾名思义,完美转发是将参数不改变属性的条件下,转发给下一个函数. 因为普通函数的参数一旦具名,始终都是lvalue. 如果把rvalue转发到下一个函数上的参数中,还是rvalue.这就是完美转发的目的。

    #include<iostream>
    using namespace std;
     
    struct X {};
    void inner(const X&) {cout << "inner(const X&)" << endl;}
    void inner(X&&) {cout << "inner(X&&)" << endl;}
    template<typename T>
    void outer(T&& t) {inner(forward<T>(t));}
     
    int main()
    {
    	X a;
    	outer(a);
    	outer(X());
    	inner(forward<X>(X()));
    }
    //inner(const X&)
    //inner(X&&)
    //inner(X&&)

    那么如何支持完美转发呢?第一反应就是用通用引用;假设如此实现:

    template<class T>
    T&& forwarding(T&& t){
      return static_cast<T&&>(param);
    }
    

     传入左值的时候是forward(x), 传入右值是forward(X()),看起来符合要求。但是这里用错了完美转发的具体场景,也就是通常我们用完美转发是什么形式呢?如果不使用完美转发,那么在template function会出现什么情况?

    template <typename T>
    void relay(T&& t) {
        cout << "in relay" << endl;
        func(t);
    }
    

     relay(temp());传入的是右值,但是转发的时候t被认为左值. 不符合完美转发语义

    template<typename T>
    void foo(T&& fparam)
    {
        std::forward<T>(fparam);
    }
    

      

     以上是完美转发的场景,完美转发配套通用引用,才是它的应用场景, 因为param已经具名,所以是lvalue,刚才的简单实现,显然不符合。

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

     以上实现,才是完美转发的主要实现,为什么是主要实现,因为它是最多场景的实现。我们分析一下foo(A());T被推导为A,fparam是lvalue,param是A&。因此匹配

    但是如果我们翻C++ 完美转发的实现:貌似还有另外一个实现:
    template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;
    这里应对什么场景呢?直接调用forward<A>(A())的场景。 注意这里typename remove_reference<T>::type&&不再是通用引用,而是右值引用。之前的左值引用,不能接右值,所以需要重定义一个函数.

    以上就实现了完美转发的所有内容.完美转发的根基是引用折叠和通用引用.
       其他:
    template< class T > struct remove_reference      {typedef T type;};
    template< class T > struct remove_reference<T&>  {typedef T type;};
    template< class T > struct remove_reference<T&&> {typedef T type;}; 
    

      

  • 相关阅读:
    一个万能的工具包下载网站
    Keras框架简介
    发现了一个非常棒的pyqt5的例子集
    人脸识别常用数据集大全(12/20更新)
    用 opencv和numpy进行图片和字符串互转,并保存至 json
    机器学习中的范数规则化-L0,L1和L2范式(转载)
    利用face_recognition库裁取人脸
    一招解决C盘空间不足,再也不怕硬盘爆满!
    【LeetCode】394.字符串解码(辅助栈、递归、详细图解)
    程序员那些事儿:女婿程序员
  • 原文地址:https://www.cnblogs.com/kkshaq/p/10445137.html
Copyright © 2020-2023  润新知