zoukankan      html  css  js  c++  java
  • 2. 函数模板二

    1. 引用包装器

    #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. 模板的嵌套:

    #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. 函数模板与引用:

    #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. 模板的默认参数:

    #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. 函数模板类型匹配:

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

        

  • 相关阅读:
    3: Flink 运行命令 设置port
    4: docker 安装flink 1.14
    6: Docker Compose简单知识
    十二 docker 安装kafka
    十三 查看kafka版本
    2: Windows安装1.9.3 flink && first demo project
    5: win10 使用IDEA调试编译flink 1.14
    1: Windows上安装Flink
    Chrome 96 新功能
    js map遍历与promise一起使用会出现的问题,以及解决方案
  • 原文地址:https://www.cnblogs.com/si-lei/p/9989783.html
Copyright © 2011-2022 走看看