函数模板参数左值,右值,引用

#include <iostream>
#include <functional>
using namespace std;

template<class T>
void valTest(T t) {
    cout << "void valTest(T t)" << endl;
    t++;
    cout << "t = " << t << endl;
}

template<class T>
void refTest(T& t) {
    cout << "void refTest(T& t)" << endl;
    t++;
    cout << "t = " << t << endl;
}

template<class T>
void moveTest(T&& t) {
    cout << "void moveTest(T&& t)" << endl;
    t++;
    cout << "t = " << t << endl;
}

//总结:
//(1)模板参数(T t);传参时ref()的是原本,其余都是副本
//(2)模板里自带引用(T& t)或者(T&& t),无论传参的是左值还是右值,其作用都在原值上

//变量、左值引用、右值引用原则上不能冲突(模板可以,没有那么严格)
//ref 变量-》左值引用
//mov 左值—》右值(避免拷贝)

int main() {
    int data = 100;
    valTest(ref(data));  // ref引用传参
    cout << "data = " << data << endl;  // 101
    cout << "===========" << endl;

                                    //data = 101
    int &&rrdata = data + 1;        //rrdata = 102
    valTest(rrdata);
    cout << "rrdata = " << rrdata << endl;  // 102
    cout << "data = " << data << endl;  // data =101
    cout << "===========" << endl;

    refTest(rrdata);              // rrdata = 102
    cout << "rrdata = " << rrdata << endl;  // 103
    cout << "data = " << data << endl;  // data =101
    cout << "===========" << endl;

    moveTest(/*reinterpret_cast<int &&>*/(rrdata)); // rrdata = 103
    cout << "rrdata = " << rrdata << endl;   // 104
    cout << "data = " << data << endl;  // data =101
    cout << "===========" << endl;


    return 0;
}

int main2() {
    int data = 100;
    int &rdata = data;
    valTest(rdata);
    cout << "rdata = " << rdata << endl;  // rdata = 100
    cout << "data = " << data << endl;  // data = 100
    cout << "===========" << endl;

    refTest(rdata);     // rdata = 100
    cout << "rdata = " << rdata << endl;  // rdata = 101
    cout << "data = " << data << endl;  // rdata = 101
    cout << "===========" << endl;

    moveTest(/*reinterpret_cast<int &&>*/(rdata)); //rdata = 101
    cout << "rdata = " << rdata << endl;   // rdata = 102
    cout << "data = " << data << endl;  // data = 102
    cout << "===========" << endl;

    //模板并没有那么严格,如果是自定义函数则无法通过编译,则需要使用move()把数据、左值引用变为右值引用
//    moveTest(move(rdata));
//    cout << "rdata = " << rdata << endl;   // 103
//    cout << "===========" << endl;
    return 0;
}

int main1() {
    int data = 100;
    valTest(data);
    cout << "data = " << data << endl;  // 100
    cout << "===========" << endl;

    refTest(data);
    cout << "data = " << data << endl;  // 101
    cout << "===========" << endl;

    moveTest(/*reinterpret_cast<int &&>*/(data));
    cout << "data = " << data << endl;   // 102
    cout << "===========" << endl;
    return 0;
}

std::ref 用于包装按引用传递的值。
std::cref 用于包装按const引用传递的。

std::move并不能移动任何内存,它唯一的功能是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值,以用于移动语义,从实现上讲,std::move基本等同于一个类型转换:static_cast<T&&>(lvalue);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值