#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);