zoukankan      html  css  js  c++  java
  • 3. STL编程三

    1. 算法容器的使用:

    #include <iostream>
    #include <functional>
    #include <vector>
    #include <algorithm>    //算法,共包含108个算法
    #include <numeric>        //整数
    
    using namespace std;
    using namespace std::placeholders;    //用于bind()函数的"_1"参数
    
    struct MyStruct
    {
        int operator()(int data)    //对()进行重载-->伪函数
        {
            return data % 2 == 1;
        }
    };
    
    int get(int data)
    {
        return data % 2 == 1;
    }
    
    struct my
    {
        int get(int data)
        {
            return data % 2 == 1;
        }
    };
    
    int main()
    {
        vector<int> myint{ 1,2,3,4,5,6,7,8,9,11 };    //创建容器
        //法一:lambda表达式
        int num1 = count_if(myint.begin(), myint.end(), [](int data)->bool {return data % 2 == 0; });    //偶数个数
        //法二:伪函数(匿名对象)
        int num2 = count_if(myint.begin(), myint.end(), MyStruct());    //MyStruct()匿名对象
        //法三:有名对象
        MyStruct my1;
        int num3 = count_if(myint.begin(), myint.end(), my1);
        //法四:函数
        int num4 = count_if(myint.begin(), myint.end(), get);
        //法五:成员函数(函数绑定器)
        my my2;
        auto fun = bind(&my::get, &my2, _1);
        int num5 = count_if(myint.begin(), myint.end(), fun);
    
        cout << num1 << endl;    //4
        cout << num2 << endl;    //6
        cout << num3 << endl;    //6
        cout << num4 << endl;    //6
        cout << num5 << endl;    //6
    
    
        system("pause");
        return 0;
    }

        

       1.1 加入函数模板如下:

    #include <iostream>
    #include <functional>
    #include <vector>
    #include <algorithm>    //算法,共包含108个算法
    #include <numeric>        //整数
    
    using namespace std;
    using namespace std::placeholders;    //用于bind()函数的"_1"参数
    
    template<class T>
    bool getT(T data)
    {
        return data % 2 == 1;
    }
    
    int main()
    {
        vector<int> myint{ 1,2,3,4,5,6,7,8,9,11 };    //创建容器
    
        int num6 = count_if(myint.begin(), myint.end(), getT<int>);
        cout << num6 << endl;    //6
    
        system("pause");
        return 0;
    }

        

    2. 模板的展开 ==> 属于模板元的范畴

    #include <iostream>
    #include <cstdarg>
    using namespace std;
    
    template<class T>
    void show(T t)
    {
        cout << t << " ";
    }
    
    template<class...Args>
    void all(Args...args)
    {
        int arr[] = { (show(args),0)... };    //使用数组进行展开
    }
    
    template<class...Args>
    void allIt(Args...args)
    {
        int arr[] = { (show(args),0)... };    //int arr[],用来约束展开多少层,保存在数组里面,[]不能省
    }
    
    int main()
    {
        all(1, 2, 3, 4, 5);
        cout << endl;
        all(1, 2, 3, 4, 5, 6, 7, 8);
        cout << endl;
        allIt(1, 'A', "123", 7.89);
        cout << endl;
    
        system("pause");
        return 0;
    }

        

    3. 函数模板推理机制:

    #include <iostream>
    using namespace std;
    
    template<typename T>    
    void go(T t)    //将类型泛型
    {
        cout << typeid(T).name() << endl;
        //cout << t << endl;
        cout << "T:" << endl;
    }
    
    template<int i>  //模板之间也可以重载
    void go()        //数据可以为任意数据(相当于数字模板)
    {
        cout << i << endl;
    }
    
    template<typename T>
    void go(T *t)    //将类型泛型
    {
        cout << typeid(T).name() << endl;
        cout << "T *:" << t << endl;
    }
    
    int main()
    {
        /*
        go(31 - 2);                 //调用泛型函数模板
    
        go<31 - 2>();               //调用数字模板
    
        go<decltype(10 + 2)>(1234); //调用泛型函数模板,可以用decltype获取数据类型
        */
    
        go(nullptr);                //nullptr不是指针类型,是一种自定义的数据类型表示空指针而已,调用go(T t)
    
        int *p = nullptr;           //调用go(T *t)
        go(p);
    
        system("pause");
        return 0;
    }

        

    4. 函数指针与函数模板:

      4.1 函数模板赋值给函数指针:

    #include <iostream>
    using namespace std;
    
    template<class T>
    void show(T t)
    {
        cout << t << endl;
    }
    
    struct MyStruct
    {
        template<class T>
        void show(T t)
        {
            cout << t << endl;
        }
    
        void go()        
        {
            show(123);
        }
    };
    
    //函数模板赋值给函数指针
    int main()
    {
        //void(*p)() = show<int>;    //无法从“void (__cdecl *)(T)”转换为“void (__cdecl *)(void)”
        void(*p1)(int i) = show<int>;
        void(*p2)(double db) = show<double>;
    
        system("pause");
        return 0;
    }

      4.2 如何调用结构体中的函数模板?

    //如何调用结构体中的函数模板?
    int main()
    {
        MyStruct my1;
        my1.go();            //结构体内部调用结构体中的函数模板
    
        my1.show(12.3);      //外部直接调用结构体中的函数模板
        my1.show('A');
        my1.show<int>('A');
    
        system("pause");
        return 0;
    }

        

      4.3 如何绑定结构体内部的函数模板?

    #include <iostream>
    #include <functional>
    
    using namespace std;
    using namespace std::placeholders;
    
    template<class T>
    void show(T t)
    {
        cout << t << endl;
    }
    
    struct MyStruct
    {
        template<class T>
        void show(T t)
        {
            cout << t << endl;
        }
    
        template<class T>
        void showit(T t1, T t2)
        {
            cout << t1 << " " << t2 << endl;
        }
    
        void go()        
        {
            show(123);
        }
    };
    
    //如何绑定结构体内部的函数模板?
    int main()
    {
        MyStruct my1;
        auto fun = bind(&MyStruct::showit<int>, &my1, 1, 2);
        fun(2);
    
        system("pause");
        return 0;
    }

        

    5. 函数模板、模板函数与类模板:

      5.1 什么是函数模板?什么是模板函数?

        函数模板就是上面所讲的函数模板,而模板函数则是实例化的函数模板

    #include <iostream>
    using namespace std;
    
    /*函数模板,不调用不编译*/
    template<class T>
    T add(T a, T b)
    {
        return a + b;
    }
    
    int main()
    {
        add(1, 2);              /*模板函数,也就是实例化的函数模板,自动根据参数推理*/
        add<double>(1, 1.2);    /*模板函数*/
    
        system("pause");
        return 0;
    }

      5.2 类成员函数模板:

    #include <iostream>
    using namespace std;
    
    class myclass
    {
    public:
        template<class T>        //类成员函数模板
        T add(T a, T b)
        {
            return a + b;
        }
    
        template<class T>        //静态函数模板
        static T sub(T a, T b)
        {
            return a - b;
        }
    };
    
    int main()
    {
        myclass *p = nullptr;
        int num1 = p->add<int>(2, 3);   //强行指定的模板函数,当做类成员函数调用
        int num2 = p->add(2, 3);        //自动推理的模板函数
        cout << num1 << endl;
        cout << num2 << endl;
    
        int num3 = myclass::sub(9 , 1);
        cout << num3 << endl;
    
        system("pause");
        return 0;
    }

        

    6. 模板在类中的应用:

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    class myclass
    {
    public:
        template<class T>
        T add(T a)
        {
            return a;
        }
    
        template<class T>
        T add(T a,T b)
        {
            show();            //函数模板与类成员函数可以互相调用
            return a + b;
        }
    
        template<class T>
        T add(T a, T b,T c)        
        {
            return a + b + c;
        }
    
        //template<class T>
        //virtual T add(T a, T b,T c)        //error C2898: “T myclass::add(T,T,T)”: 成员函数模板不能是虚拟的
        //{
        //    return a + b + c;
        //}
    
        void show()
        {
            cout << add<int>(10) << endl;    //指明类型的方式调用
        }
    
    };
    
    int main()
    {
        myclass *p = nullptr;
        p->add(1, 2);
    
        system("pause");
        return 0;
    }

    7. 类模板与函数模板对比:

    #include <iostream>
    #include <initializer_list>
    #include <memory>
    #include <string>
    using namespace std;
    
    template<class T,int n>
    class myarray
    {
        T *p;
    public:
        myarray(initializer_list<T> mylist)
        {
            p = new T[n];                //开辟内存
            memset(p, 0, sizeof(T)*n);   //内存清0
            
            int length = mylist.size();
            if (length > n)
            {
                abort();    //触发异常
            }
            else
            {
                int i = 0;
                for (auto j : mylist)    //数据填充
                {
                    p[i] = j;
                    i++;
                }
            }
        }
    
        ~myarray()
        {
            delete[] p;
        }
    
        void show()    //显示数据
        {
            for (int i = 0; i < n; i++)
            {
                cout << p[i] << " ";
            }
            cout << endl;
        }
    
        void sort()    //冒泡排序
        {
            for (int i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < n - 1 - i; j++)
                {
                    if (p[j] < p[j+1])    //从大到小
                    {
                        T temp = p[j];
                        p[j] = p[j + 1];
                        p[j + 1] = temp;
                    }
                }
            }
        }
    };
    
    int main()
    {
        myarray<int, 10> my1 = { 1,2,3,4,5,6,7,8,9 };
        my1.show();
        my1.sort();
        my1.show();
    
        myarray<double, 5> my2 = { 1.1,2.2,3.3,4.4,5.5 };
        my2.show();
        my2.sort();
        my2.show();
    
        myarray<string, 5> my3 = { "123","abcdef","sdaf","hello" };
        my3.show();
        my3.sort();
        my3.show();
    
        system("pause");
        return 0;
    }

        

    8. 类包装器:

    #include <iostream>
    using namespace std;
    
    template<class T,class F>    //函数模板
    T run(T t, F f)
    {
        return f(t);
    }
    
    class fun
    {
    public:
        double operator ()(double data)
        {
            return data - 10;
        }
    
    };
    
    template<class T>    //类模板
    class Tfun
    {
    public:
        T operator ()(T data)
        {
            return data - 10;
        }
    
    };
    
    int main()
    {
        cout << run(10.9, fun()) << endl;            //fun()是匿名对象
        fun x;
        cout << run(10.9, x) << endl;                //x是有名对象
    
        cout << run(10.9, Tfun<double>()) << endl;   //模板函数的匿名对象,构造函数返回的就是匿名对象
        Tfun<double> fang;
        cout << run(10.9, fang) << endl;
    
        system("pause");
        return 0;
    }

        

    9. 高级类包装器:

    #include <iostream>
    #include <list>
    #include <vector>
    using namespace std;
    
    template<class T, class F>    //函数模板
    T run(T t, F f)
    {
        return f(t);
    }
    
    template<class T>    //类模板
    class Trun
    {
    public:
        T operator ()(T data)
        {
            for (auto i:data)
            {
                cout << i <<" ";
            }
            cout << endl;
            return data;
        }
    
    };
    
    int main()
    {
        list<int> myint;    //构建链表,压入数据
        for (int i = 0; i < 5; i++)
        {
            myint.push_back(i);
        }
    
        run(myint,                            //lambda表达式
            [](list<int> myint)->list<int> 
            {
                for (auto i : myint)
                {
                    cout << i << endl;
                }
                return myint;
            }
            );
    
        system("pause");
        return 0;
    }

        

    #include <iostream>
    #include <list>
    #include <vector>
    using namespace std;
    
    template<class T, class F>    //函数模板
    T run(T t, F f)
    {
        return f(t);
    }
    
    template<class T>    //类模板
    class Trun
    {
    public:
        T operator ()(T data)
        {
            for (auto i:data)
            {
                cout << i <<" ";
            }
            cout << endl;
            return data;
        }
    
    };
    
    int main()
    {
        vector<int> myv{ 1,2,3,4,5,7,8 };
        run(myv, Trun< vector<int> >());    //匿名对象,用完就扔
        run(myv, Trun< decltype(myv) >());
    
        system("pause");
        return 0;
    }

        

     10. 类模板间的封装、继承、多态:

      10.1 父类为类模板,子类也是类模板:

    #include <iostream>
    using namespace std;
    
    //类模板支持封装、继承、多态
    template<class T>
    class Tfu
    {
    public:
        T t;
        Tfu():t(0)
        {
        }
    
        void show()
        {
            cout << t << endl;
        }
    
        virtual void go()
        {
            cout << "fu:" << t << endl;
        }
    };
    
    template<class T>
    class Tzi :public Tfu<T>
    {
    public:    
        void go()
        {
            cout << "zi:" << t << endl;
        }
    };
    
    int main()
    {
        Tzi<int> tzi;
        tzi.t = 109;
        tzi.show();
    
        Tfu<int> *p = new Tzi<int>;    //实现多态
        p->go();
    
        system("pause");
        return 0;
    }

        

      10.2 父类为类模板,子类为普通类:

    #include <iostream>
    using namespace std;
    
    template<class T>
    class Tfu
    {
    public:
        T t;
        Tfu() :t(0)
        {
        }
    
        void show()
        {
            cout << t << endl;
        }
    
        virtual void go()
        {
            cout << "fu:" << t << endl;
        }
    };
    
    class zi :public Tfu<int>
    {
    public:
        void go()
        {
            cout << "zi:" << t << endl;
        }
    };
    
    int main()
    {
        zi z1;
        z1.t = 108;
        z1.show();
    
        Tfu<int> *p = new zi;    //多态    此处只能用int
        p->go();
    
        system("pause");
        return 0;
    }

        

      10.3  父类为普通类,子类为类模板:

    #include <iostream>
    using namespace std;
    
    //类模板支持封装、继承、多态
    
    //T    T    //类模板        可以实现封装、继承、多态
    //T    P    //类模板与类    可以实现封装、继承、多态    必须明确类型
    //P    T    //类与类模板    可以实现封装、继承、多态    必须明确类型    多态什么类型都可以
    //P    P    //普通类        可以实现封装、继承、多态
    class die
    {
    public:
        int t;
        die() :t(0)
        {
        }
    
        void show()
        {
            cout << t << endl;
        }
    
        virtual void go()
        {
            cout << "fu: " << t << endl;
        }
    };
    
    template<class T>
    class er :public die
    {
    public:
        void go()
        {
            cout << typeid(T).name() << "   zi: " << t << endl;
        }
    
    };
    
    int main()
    {
        er<double> boer;
        boer.show();
    
        die *p1 = new er<char>;
        die *p2 = new er<int>;
        die *p3 = new er<double>;
        p1->go();
        p2->go();
        p3->go();
    
        system("pause");
        return 0;
    }

        

  • 相关阅读:
    解决Visual Code安装中文插件失败问题
    【转】python的复制,深拷贝和浅拷贝的区别
    Python中正则匹配使用findall时的注意事项
    【转载】正则表达式全部符号解释
    旧文章搬运完毕
    【旧文章搬运】VC插件中如何获取当前工程的工作目录
    【旧文章搬运】在64位系统上调试32位程序
    NLP常见任务介绍
    window10下pytorch和torchvision CPU版本安装
    tensorflow2.0安装
  • 原文地址:https://www.cnblogs.com/si-lei/p/9993809.html
Copyright © 2011-2022 走看看