C++完美转发的实现

目录

一.完美转发 

1.转发的含义:就是函数参数的转发。

2.完美转发的含义:函数参数传递的过程中,避免拷贝移动的操作,函数参数的左值性和右值性保持不变,也就是参数的类型和属性不发生变化

3.函数参数传递的方式

 4.实现完美转发

  实现完美转发需要C++的三种技术


一.完美转发 

1.转发的含义:就是函数参数的转发。

2.完美转发的含义:函数参数传递的过程中,避免拷贝移动的操作,函数参数的左值性和右值性保持不变,也就是参数的类型和属性不发生变化

3.函数参数传递的方式

 4.实现完美转发

  实现完美转发需要C++的三种技术

1.函数模板

2.引用折叠

3.forward<T>   =    static_cast<T&&>()

下面就这三种技术来实现完美转发,结合C++make_开头的工厂函数我们来实现自定义简单的工厂函数


#include <iostream>
using namespace std;

struct _person
{
    _person(string&) {
        cout << "左值" << endl;
    }
    _person(string&&) {
        cout << "右值" << endl;
    }
};

//1.值传递的方式    
_person make_factory(string person) {

    return _person(person);

}
//结果:会造成拷贝操作,结果都为左值



//2.左值引用传递的方式
_person make_factory(string& person) {

    return _person(person);

}
//结果:调用函数会报错

//3..右值值引用传递的方式
_person make_factory(string&& person) {

    return _person(person);

}
//结果:调用函数会报错

//4..connst引用传递的方式
_person make_factory(string& person) {

    return _person(person);

}
//使得传递的参数增加const性,构造函数无法匹配


void test() {
    string str = "xiaozhang";

    //传递左值
    make_factory(str);

    //传递右值
    make_factory(move(str));
}

int main()
{
    test();
    return 0;
}

 我们希望参数是“原封不动”的性质,所以上面这些方式都不能实现,那我们如何去解决这个问题呢,C++支持模板技术,对于函数模板,可以实现类型的自动推导,加上引用折叠的技术

引用折叠:T&& 多种类型做合在一起的时候,通过编译器的一组规则确定最终的引用


#include <iostream>
using namespace std;

struct _person
{
    _person(string&) {
        cout << "左值" << endl;
    }
    _person(string&&) {
        cout << "右值" << endl;
    }
};

//函数模板
template<class T>
 
_person make_factory(T&& person) {

    return _person(person);

}


void test() {
    string str = "xiaozhang";

    //传递左值
    make_factory(str);

    //传递右值
    make_factory(move(str));
}

int main()
{
    test();
    return 0;
}

 运行结果发现

左值
左值

结果还是不对,原因是什么呢

右值引用:可以这么理解,右值是即将废弃的对象,右值引用的目的就是为了给这些废弃的对续命,此时,无论左值,右值对象都变成了具名对象,变成了左值对象了,所以才出现这样的结果。

只要把参数转化回去就行了stctic_cast<T&&>(),或者使用forwardforward<T>函数就行了,forward<T>函数底层就是强制转换这种方式


#include <iostream>
using namespace std;

struct _person
{
    _person(string&) {
        cout << "左值" << endl;
    }
    _person(string&&) {
        cout << "右值" << endl;
    }
};

//函数模板
template<class T>
 
_person make_factory(T&& person) {

    return _person(static_cast<T&&>(person));

}


void test() {
    string str = "xiaozhang";

    //传递左值
    make_factory(str);

    //传递右值
    make_factory(move(str));
}

int main()
{
    test();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值