2. 函數模板二

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;
}

    

相關文章
相關標籤/搜索