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;}; 
    

      

  • 相关阅读:
    没有完成的题目
    哈尔滨工程大学 ACM online contest 1008 how many
    POJ 2976 分数规划
    长沙理工 ACM 数位 DP 1488
    POJ 2663
    USETC 1821 AC 自动机
    长沙理工 ACM 分数规划 1494
    正则表达式基础知识(转)
    上传头像代码
    datalist 分页(转)
  • 原文地址:https://www.cnblogs.com/kkshaq/p/10445137.html
Copyright © 2011-2022 走看看