c++代码心得体会-关于c++11 完美转发 std::forward()

std::forward
右值引用类型是独立于值的,一个右值引用参数作为函数的形参,在函数内部再转发该参数的时候它已经变成一个左值,并不是他原来的类型。

如果我们需要一种方法能够按照参数原来的类型转发到另一个函数,这种转发类型称为完美转发。

forward可以保持实参的类型、左值右值、是否const

forward的原型大致如下

template< typename T > inline
T&& forward( typename std::remove_reference<T>::type& t ) noexcept {
    return (static_cast<T&&>(t));
}

template< typename T > inline
T&& forward( typename std::remove_reference<T>::type&& t ) noexcept {
    static_assert(!is_lvalue_reference<T>::value, "bad forward call");
    return (static_cast<T&&>(t));
}


move原型
template <typename T>
typename std::remove_reference<T>::type&& move (T&& t) {
    return static_cast<typename std::remove_reference<T>::type&&>(t);
}

 

示例:

template<typename T>
void print(T& t){
    cout << "L " << endl;
}
template<typename T>
void print(T&& t){
    cout << "R " << endl;
}

/*
参考官方解答 https://zh.cppreference.com/w/cpp/utility/forward
若对 wrapper() 的调用传递右值 int ,则推导 T 为 int (非int& 或 int&&),且 std::forward 确保将右值引用传递给 print。
若对 wrapper() 的调用传递 const 左值 int ,则推导 T 为 const int& ,且 std::forward 确保将 const 左值引用传递给 print。
若对 wrapper() 的调用传递非 const 左值 int ,则推导 T 为 int& ,且 std::forward 确保将非 const 左值引用传递给 print
*/
template<typename T>
void wrapper(T && v){    // v始终是左值
    /*
        进入该函数后,v就成了一个变量。无论它是具名右值,还是左值。
        再往下调用函数传参,都把它当变量,无法把一个变量赋值给另一个右值。
        如 int &&tmp = v; 错误的,不能把一个右值引用绑定到一个右值引用类型的变量上。
    */

    print(v);    //永远匹配上面的左值函数,打印L
    print(std::forward<T>(v));    //返回类型是T&&,所以只和T有关,做引用折叠。只有T是类似int&时,才返回左值。
    print(std::move(v));    //返回类型是T::type&&,永远是返回右值,匹配上面的右值函数,打印R
}

int main(){
    wrapper(1);    //L R R 左值 右值 右值
    int x = 1;
    wrapper(x);    //L L R
    wrapper(std::forward<int>(x));    //L R R
    wrapper(std::forward<int&>(x));    //L L R
    wrapper(std::forward<int&&>(x));    //L R R
    wrapper(std::forward<const int>(x));    //L R R

    auto &&y = x;
    auto &&z = 3;
    wrapper(y);    //L L R
    wrapper(z);    //L L R

    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值