zoukankan      html  css  js  c++  java
  • 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;}; 
    

      

  • 相关阅读:
    C/C++ 知识点---存储区
    Objective-C中的@property和@synthesize用法
    C/C++ 知识点---数组与指针
    C/C++ 知识点---C语言关键字(32个)
    js里json和eval()
    js--冒泡排序
    js数学公式-曲线运动
    事件绑定兼容(事件流的机制;事件委托
    2 获取元素在页面中的位置
    Dom关于位置和尺寸的api
  • 原文地址:https://www.cnblogs.com/kkshaq/p/10445137.html
Copyright © 2011-2022 走看看