1. 引用包裝器ios
#include <iostream> using namespace std; void change(int &num) //引用做爲參數 { num = 3; } int main1001() { int data = 100; //change(data); //cout << data << endl; //3 int &rdata(data); change(rdata); cout << data << endl; //3 system("pause"); return 0; } template<class T> void show(T t) //函數模板 法一:將函數模板改成引用 void show(T & t) { cout << t << endl; t += 10; } int main() { double db(1.0); double &rdb(db); //show(db); //1 //show(rdb); //1 若想改成11,有兩種辦法 show(ref(rdb)); //法二:引用包裝器,ref聲明爲引用 cout << "db:" << db << endl; system("pause"); return 0; }
2. 函數模板與函數包裝器:函數
#include <iostream> #include <functional> //函數包裝器的頭文件 using namespace std; using std::function; int add(int a, int b) { return a + b; } template<class T,class F> T run(T t1, T t2, F f) //做爲通用的接口,任何數據類型,任何函數均可以 { return f(t1, t2); } int main() { function<int(int, int)> fun1 = add; //包裝函數 function<int(int, int)> fun2 = [](int a, int b)->int {return a - b; }; cout << fun1(10, 19) << endl; cout << run(10, 19, fun1) << endl; //默認推導,原生函數優先 cout << run<int>(10, 19, fun1) << endl; //指定爲int類型 cout << run<int, function<int(int, int)>>(10, 19, fun1) << endl; //強行指定類型,前面是T的類型,後面是F的類型 cout << fun2(10, 19) << endl; system("pause"); return 0; }
3. 模板的嵌套:spa
#include <iostream> #include <vector> #include <list> using namespace std; template<class T> void showallA(vector<T> v) { for (auto i:v) { cout << i << " "; } cout << endl; } template<class T1,class T2> void showallB(vector<T1> v,list<T2> l) //模板的嵌套 { for (auto i : v) { cout << i << " "; } cout << endl; for (auto i:l) { cout << i << " "; } cout << endl; } int main() { vector<int> myint1{ 1,2,3,4,5 }; vector<char> mych1{ 'A','B','C','D','E' }; list<int> myint2{ 1,2,3,4,5 }; list<char> mych2{ 'A','B','C','D','E' }; showallA(myint1); showallA(mych1); showallB(myint1, myint2); showallB(mych1, mych2); system("pause"); return 0; }
4. 函數模板與引用:3d
#include <iostream> using namespace std; //變量、左值引用、右值引用,原則上不能衝突 //ref: 變量->左值引用 //move: 左值引用->右值引用 template<class T> void print1(T t) //數據 { cout << "print(T t):"; t += 1; cout << t << endl; } template<class T> void print2(T & t) //左值引用 { cout << "print(T & t):"; t += 1; cout << t << endl; } template<class T> void print3(T && t) //右值引用 { cout << "print(T && t):"; t += 1; cout << t << endl; } int main() { int data = 100; //數據 int & rdata(data); //左值引用,4字節 int && rrdata(data + 1); //右值引用,4字節 //print1(data); //101 副本 //cout << "data=" << data << endl; //100 //print1(ref(data)); //101 本來 引用包裝器,包裝變量或引用 //cout << "data=" << data << endl; //101 //print1(rdata); //101 副本 //cout << "data=" << data << endl; //100 //print1(rrdata); //102 副本 右值引用內存保存的臨時值 //cout << "data=" << data << endl; //100 //cout << "rdata=" << rdata << endl; //100 //cout << "rrdata=" << rrdata << endl; //101 print1(ref(rrdata)); //102 本來 右值引用內存保存的臨時值 cout << "data=" << data << endl; //100 cout << "rdata=" << rdata << endl; //100 cout << "rrdata=" << rrdata << endl; //102 system("pause"); return 0; }
//模板自帶引用,不管是 & 仍是 && //T t,帶有ref都是本來,不然都是副本 int main() { int data = 100; //數據 int & rdata(data); //左值引用,4字節 int && rrdata(data + 1);//右值引用,4字節 /* print2(data); //101 模板自帶引用,都是本來 cout << "data=" << data << endl; //101 cout << "rdata=" << rdata << endl; //101 cout << "rrdata=" << rrdata << endl; //101 print2(rdata); //101 cout << "data=" << data << endl; //101 cout << "rdata=" << rdata << endl; //101 cout << "rrdata=" << rrdata << endl; //101 print2(rrdata); //102 cout << "data=" << data << endl; //101 cout << "rdata=" << rdata << endl; //101 cout << "rrdata=" << rrdata << endl; //102 print3(data); //101 cout << "data=" << data << endl; //101 cout << "rdata=" << rdata << endl; //101 cout << "rrdata=" << rrdata << endl; //101 print3(rdata); //101 cout << "data=" << data << endl; //101 cout << "rdata=" << rdata << endl; //101 cout << "rrdata=" << rrdata << endl; //101 */ print3(rrdata); //102 cout << "data=" << data << endl; //100 cout << "rdata=" << rdata << endl; //100 cout << "rrdata=" << rrdata << endl; //102 system("pause"); return 0; }
//不是函數模板,須要嚴格地類型匹配 void printInt(int && t) { cout << t << endl; } int main() { int num = 10; int & rnum(num); //printInt(num); //沒法將參數 1 從「int」轉換爲「int &&」 //printInt(rnum); //沒法將參數 1 從「int」轉換爲「int &&」 printInt(rnum+1); //11 printInt(move(num)); //10 移動語義,數據或者左值 轉換爲右值 printInt(move(rnum)); //10 system("pause"); return 0; }
5. 函數模板的重載:指針
#include <iostream> using namespace std; //函數模板的重載:參數的個數不同、類型不同、順序不同(與返回值無關) //有指針要優先匹配指針 template<class T> void go(T t1) { cout << "T:"; cout << t1 << endl; } template<class T> void go(T * t1) { cout << "T * :"; cout << t1 << endl; } int main() { int *p = new int[5]{ 1,2,3,4,5 }; go(p[0]); go(p); go(&p); //地址趨向地址 system("pause"); return 0; }
6. 模板的默認參數:code
#include <iostream> using namespace std; template<class T = int> //模板參數能夠有默認值 void BoBo(T t) { cout << t << endl; } template<class T = int, int n = 10> //模板參數能夠有默認值 void bobo(T t) { cout << "n:" << n << endl; cout << "t:" << t << endl; } int main() { BoBo(25); //25 BoBo(25.52); //25.52 自動推理 BoBo<>(25.52); //25.52 自動推理 BoBo<int>(25.52); //25 bobo<int>(25.52); //n:10 t:25 bobo<int,250>(25.52); //n:250 t:25 system("pause"); return 0; }
//節約輸入參數的做用,類型參數能夠有的指定有的不指定,填充是從左到右,必須覆蓋類型參數 //函數參數,默認的都要統一在右邊,至少要把不默認的填充了才能調用 template<class T1 = int, class T2 , class T3 = double, class T4 = double> //參數類型一樣能夠設置默認 void BoDa(T1 t1=250.1,T2 t2=250.11,T3 t3=250.111,T4 t4=250.1111) //參數值能夠設置爲默認值 { cout << t1 << " " << t2 << " " << t3 << " " << t4 << endl; } int main() { BoDa<int,int>(); //250 250 250.111 250.1111 BoDa(1, 2, 3, 4); //1 2 3 4 system("pause"); return 0; }
7. 函數模板類型匹配:blog
#include <iostream> using namespace std; //模板會自動匹配*號多的函數 template<class T> void com(T *p) { cout << "*:"; cout << typeid(T).name() << endl; } template<class T> void com(T **p) { cout << "**:"; cout << typeid(T).name() << endl; } int main() { int *p = nullptr; int **pp = nullptr; int ***ppp = nullptr; com(p); com(pp); com(ppp); system("pause"); return 0; }