右值引用和完美转发的实现

1.右值分为纯右值和将亡值,

  纯右值:1、a+b

  将亡值:临时对象、匿名对象

2.右值和左值的本质区别是能不能取地址

3.引用的使用

   const 左值引用可以接收右值

  右值引用不能接收左值,只接收右值

   左值可以强制类型转换右值引用变成右值

   右值引用类型的变量是左值,是可以取地址的(比如int&& a)

4.引用折叠:c++不允许引用的引用,会合并

& &&-》&           && &-》&           && &&-》&&           & &-》&

5.万能引用

        1.最经典是函数模板中的应用

#include <iostream>

template <typename T>
void wrapper(T &&u) { // 万能引用
    func(std::forward<T>(u)); // 完美转发
}

class MyClass {};

void func(MyClass& a) { std::cout << "in func(MyClass&)\n"; }
void func(const MyClass& a) { std::cout << "in func(const MyClass&)\n"; }
void func(MyClass&& a) { std::cout << "in func(MyClass &&)\n"; }

int main(void) {
    MyClass a;
    const MyClass b;

    func(a);
    func(b);
    func(MyClass());

    std::cout << "----- Wrapper ------\n";
    wrapper(a);
    wrapper(b);
    wrapper(MyClass());

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

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

在上面的例子中,wrapper万能引用的模板参数是推导给的,而forward完美转发的模板参数是显式给的

前三个func去找最好吃的,结果很明显。

1.看后三个,a是左值,wrapper的类型模板参数T被推导为MyClass&,forward的类型模板参数T给了MyClass&,在forward中会强制类型转换u为Myclass& &&,forward最后返回的u就是MyClass&,然后执行第一个func ,不用去管调了哪一个forward,反正最后强转的类型一样。

2.b是左值,wrapper的T推导是const myclass &,u的类型折叠后是const myclass&,forward的T给const myclass&,在forward中会强制类型转换u为const Myclass& &&,forward最后返回的u就是const MyClass&,执行第二个func。

3.myclass()是匿名对象,妥妥右值,wrapper的T推导是 myclass &&,u的类型折叠后是myclass&&,在forward中会强制类型转换u为 Myclass&& &&,forward最后返回的u就是 MyClass&&,调第三个func。如果没有完美转发,那直接使用u,u是右值引用类型是个左值,会调func(myclass&),forward相当于把左值u强转了一下,成了右值,会调func(myclass&&)

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

move可以将左值变为右值,本质不也是强转左值为右值引用类型使其变为右值

假设t是左值myclass类型,那这里万能引用T推导为myclass &,这里最后强转为myclass&&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值