• 【足迹C++primer】48、函数引用操作符


    函数引用操作符

    struct absInt
    {
        int operator()(int val) const
        {
            cout<<val<<"<->!!!"<<endl;
            return val<0 ? -val : val;
        }
    };
    

    void fun1()
    {
        int i=-42;
        absInt absObj;
        int ui=absObj(i);
    }
    



    Function-Object Classes with State
    函数对象类的状态

    class PrintString
    {
    public:
        PrintString(ostream &o=cout, char c=' '):os(o), sep(c) {}   //构造函数
        void operator()(const string &s) const {os<<">>>>-----<<<<"<<s<<sep<<"yeah!"<<endl;}   //函数操纵符
        void operator()(const int i, const string &s1, const string &s2) const
        {
            if(i)
            {
                os<<"3 个參数 cutter_point-"<<s1<<endl;
            }
            else
            {
                os<<"3 个參数 cutter_point-"<<s2<<endl;
            }
        }
    
    private:
        ostream &os;    //输出流
        char    sep;
    };
    
    void fun2()
    {
        string s="cutter_point";
        PrintString printer;        //默认构造函数
        printer(s);     //调用操作符函数,输出:>>>>-----<<<<cutter_point yeah!
        PrintString errors(cerr, '
    '); //上面yeah!前面变成换行
        errors(s);
    
        vector<string> vs;
        for(size_t i=0 ; i != 7 ; ++i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            vs.push_back(ss.str());
        }
        for_each(vs.begin(), vs.end(), PrintString(cerr, '
    '));
    
        PrintString three;
        three(1, "我就是这么屌!", "没有,也就一般般啦!");
    }
    

    14.8.1. Lambdas Are Function Objects

    void fun3()
    {
        vector<string> words;
        for(size_t i=0 ; i != 7 ; ++i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()<b.size();});
        for_each(words.begin(), words.end(), PrintString(cout, '3'));
    }
    
    class ShorterString
    {
    public:
        bool operator()(const string &s1, const string &s2) const
        {return s1.size()<s2.size(); }
    };
    
    void fun4()
    {
        vector<string> words;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        stable_sort(words.begin(), words.end(), ShorterString());
        for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
            cout<<*it<<"	";
    }
    


    Classes Representing Lambdas with Captures

    void fun5()
    {
        vector<string> words;
        vector<string>::size_type sz=5;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        //得到一个指向第一个s.size()>sz的元素
        auto wc=find_if(words.begin(), words.end(), [sz](const string &a){return a.size() >= sz;});
        for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
            cout<<*it<<"	";
        if(wc != words.end())
        {
            cout<<"wc:"<<*wc<<endl;
        }
    
    }
    
    class SizeComp
    {
    public:
        SizeComp(size_t n):sz(n) {} //构造函数
        bool operator()(const string &s) const {return s.size()>=sz;}
    private:
        size_t sz;
    };
    
    void fun6()
    {
        vector<string> words;
        vector<string>::size_type sz=6;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        //得到一个指向第一个s.size()>sz的元素
        auto wc=find_if(words.begin(), words.end(), SizeComp(sz));
        ///这里为什么会引用operator()操作呢??
    
        cout<<endl;
        if(wc != words.end())
        {
            cout<<"wc:"<<*wc<<endl;
        }
    }
    


    14.8.2. Library-Defined Function Objects


    void fun7()
    {
        plus<int> intAdd;       //这个是能够加两个int型数字
        negate<int> intNegate;  //求相反数
        int sum=intAdd(10, 20); //结果30
        cout<<sum<<endl;
        sum=intNegate(intAdd(10, 20));  //结果-30
        cout<<sum<<endl;
        sum=intAdd(10, intNegate(10));  //结果0
        cout<<sum<<endl;
    }
    

    Using a Library Function Object with the Algorithms
    void fun8()
    {
        vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
        //通过一个暂时的函数对象应用<操作对两个string
        sort(svec.begin(), svec.end(), greater<string>());
        //输出结果按字典位置排序,然后大写在后,递减排序
        for_each(svec.begin(), svec.end(), [](string &s){cout<<s<<"	";});
    }
    

    通过指针直接操作内存的地址,来改变排序

    void fun9()
    {
        vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
        vector<string*> nameTable;
        for(vector<string>::iterator it=svec.begin() ; it != svec.end() ; ++it)
        {
            string* s=new string;   //这里new string一定要加!!,为了给s分配空间
            *s=*it;
            nameTable.push_back(s);
        }
    
    //    sort(nameTable.begin(), nameTable.end(), [](string* a, string* b){return a<b;});
        sort(nameTable.begin(), nameTable.end(), less<string*>());
        //输出的是按内存位置来输出的
        for(vector<string*>::iterator it=nameTable.begin() ; it != nameTable.end() ; ++it)
            cout<<*(*it)<<"	";
    }
    


    14.8.3. Callable Objects and function
    可调用对象和函数


    Different Types Can Have the Same Call Signature


    int add(int i, int j) {return i+j;}
    void fun10()
    {
        auto mod=[](int i, int j){return i%j;};
    }
    struct div2 //这里不要用div好像是和stdlib.h冲突了
    {
        int operator()(int denominator, int divisor){return denominator/divisor;}
    };
    
    //上面三个都是int(int, int)类型的
    

    我们能够定义一个map,用string类型来关联对应的函数,用string作为标识
    void fun11()
    {
        auto mod=[](int i, int j){return i%j;};
        map<string, int(*)(int, int)> binops;   //这是一个函数指针,返回一个int类型
        //这里add是一个指向+运算的指针,div是不能这样加的,它不是指针
        binops.insert({"+", add});
        binops.insert({"%", mod});
    //    binops.insert({"/", div2});
    }
    

    库函数类型


    void fun12()
    {
        function<int(int, int)> f1=add;     //函数指针,这个是加法
        function<int(int, int)> f2=div2();   //调用()操作符,这个是除法
        function<int(int, int)> f3=[](int i, int j) {return i*j;};  //lambda返回乘法
        cout<<f1(4,2)<<endl;    //6
        cout<<f2(4,2)<<endl;    //2
        cout<<f3(4,2)<<endl;    //8
    }
    
    void fun13()
    {
        auto mod=[](int i, int j){return i%j;};
        map<string, function<int(int, int)>> binops=
        {
            {"+", add},{"-", std::minus<int>()},{"/", div2()},{"*", [](int i, int j){return i*j;}},
            {"%", mod}
        };  //这个map有五个元素,当我们索引这个map的时候,我们能够调用这五个函数类型
    
        cout<<"+ <--->"<<binops["+"](10, 5)<<endl;
        cout<<"- <--->"<<binops["-"](10, 5)<<endl;
        cout<<"/ <--->"<<binops["/"](10, 5)<<endl;
        cout<<"* <--->"<<binops["*"](10, 5)<<endl;
        cout<<"% <--->"<<binops["%"](10, 5)<<endl;
    }
    


    Overloaded Functions and function
    重载的函数和功能

    void fun14()
    {
        map<string, function<int(int, int)>> binops;
        int (*fp)(int, int)=add;
        binops.insert({"+", fp});   //用函数指针来避免重载,或者同名函数的含糊不清
        //含有一个非常好的办法就是使用lambda来消除歧义是非常好的
        binops.insert({"+", [](int a, int b){return add(a,b);}});
    
    }
    

    在新的库函数类是不相关的类命名为
    unary_function和binary_function是较早的版本号的一部分
    标准库。这些类被更一般的结合使用函数代替

    全代码!


    /**
    * 功能:函数引用操作符
    * 时间:2014年7月18日16:11:45
    * 作者:cutter_point
    */
    
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<sstream>
    #include<string>
    #include<map>
    #include<functional>
    
    using namespace std;
    
    struct absInt
    {
        int operator()(int val) const
        {
            cout<<val<<"<->!!!"<<endl;
            return val<0 ? -val : val;
        }
    };
    
    void fun1()
    {
        int i=-42;
        absInt absObj;
        int ui=absObj(i);
    }
    
    /**
    Function-Object Classes with State
    函数对象类的状态
    */
    class PrintString
    {
    public:
        PrintString(ostream &o=cout, char c=' '):os(o), sep(c) {}   //构造函数
        void operator()(const string &s) const {os<<">>>>-----<<<<"<<s<<sep<<"yeah!"<<endl;}   //函数操纵符
        void operator()(const int i, const string &s1, const string &s2) const
        {
            if(i)
            {
                os<<"3 个參数 cutter_point-"<<s1<<endl;
            }
            else
            {
                os<<"3 个參数 cutter_point-"<<s2<<endl;
            }
        }
    
    private:
        ostream &os;    //输出流
        char    sep;
    };
    
    void fun2()
    {
        string s="cutter_point";
        PrintString printer;        //默认构造函数
        printer(s);     //调用操作符函数,输出:>>>>-----<<<<cutter_point yeah!
        PrintString errors(cerr, '
    '); //上面yeah!前面变成换行
        errors(s);
    
        vector<string> vs;
        for(size_t i=0 ; i != 7 ; ++i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            vs.push_back(ss.str());
        }
        for_each(vs.begin(), vs.end(), PrintString(cerr, '
    '));
    
        PrintString three;
        three(1, "我就是这么屌!", "没有,也就一般般啦!");
    }
    
    /**
    14.8.1. Lambdas Are Function Objects
    */
    void fun3()
    {
        vector<string> words;
        for(size_t i=0 ; i != 7 ; ++i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()<b.size();});
        for_each(words.begin(), words.end(), PrintString(cout, '3'));
    }
    
    class ShorterString
    {
    public:
        bool operator()(const string &s1, const string &s2) const
        {return s1.size()<s2.size(); }
    };
    
    void fun4()
    {
        vector<string> words;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        stable_sort(words.begin(), words.end(), ShorterString());
        for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
            cout<<*it<<"	";
    }
    
    /**
    Classes Representing Lambdas with Captures
    */
    void fun5()
    {
        vector<string> words;
        vector<string>::size_type sz=5;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        //得到一个指向第一个s.size()>sz的元素
        auto wc=find_if(words.begin(), words.end(), [sz](const string &a){return a.size() >= sz;});
        for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
            cout<<*it<<"	";
        if(wc != words.end())
        {
            cout<<"wc:"<<*wc<<endl;
        }
    
    }
    
    class SizeComp
    {
    public:
        SizeComp(size_t n):sz(n) {} //构造函数
        bool operator()(const string &s) const {return s.size()>=sz;}
    private:
        size_t sz;
    };
    
    void fun6()
    {
        vector<string> words;
        vector<string>::size_type sz=6;
        for(size_t i=8 ; i != -1 ; --i)
        {
            stringstream ss;
            ss<<i<<"-cutter_point";
            words.push_back(ss.str());
        }
        words.push_back("test排序");
    
        //得到一个指向第一个s.size()>sz的元素
        auto wc=find_if(words.begin(), words.end(), SizeComp(sz));
        ///这里为什么会引用operator()操作呢??
    
        cout<<endl;
        if(wc != words.end())
        {
            cout<<"wc:"<<*wc<<endl;
        }
    }
    
    /**************************************
    14.8.2. Library-Defined Function Objects
    **************************************/
    void fun7()
    {
        plus<int> intAdd;       //这个是能够加两个int型数字
        negate<int> intNegate;  //求相反数
        int sum=intAdd(10, 20); //结果30
        cout<<sum<<endl;
        sum=intNegate(intAdd(10, 20));  //结果-30
        cout<<sum<<endl;
        sum=intAdd(10, intNegate(10));  //结果0
        cout<<sum<<endl;
    }
    
    /**************************************
    Using a Library Function Object with the Algorithms
    **************************************/
    void fun8()
    {
        vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
        //通过一个暂时的函数对象应用<操作对两个string
        sort(svec.begin(), svec.end(), greater<string>());
        //输出结果按字典位置排序,然后大写在后,递减排序
        for_each(svec.begin(), svec.end(), [](string &s){cout<<s<<"	";});
    }
    
    //通过指针直接操作内存的地址,来改变排序
    void fun9()
    {
        vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
        vector<string*> nameTable;
        for(vector<string>::iterator it=svec.begin() ; it != svec.end() ; ++it)
        {
            string* s=new string;   //这里new string一定要加!!,为了给s分配空间
            *s=*it;
            nameTable.push_back(s);
        }
    
    //    sort(nameTable.begin(), nameTable.end(), [](string* a, string* b){return a<b;});
        sort(nameTable.begin(), nameTable.end(), less<string*>());
        //输出的是按内存位置来输出的
        for(vector<string*>::iterator it=nameTable.begin() ; it != nameTable.end() ; ++it)
            cout<<*(*it)<<"	";
    }
    
    /**************************************
    14.8.3. Callable Objects and function
    可调用对象和函数
    **************************************/
    
    /**
    Different Types Can Have the Same Call Signature
    */
    int add(int i, int j) {return i+j;}
    void fun10()
    {
        auto mod=[](int i, int j){return i%j;};
    }
    struct div2 //这里不要用div好像是和stdlib.h冲突了
    {
        int operator()(int denominator, int divisor){return denominator/divisor;}
    };
    
    //上面三个都是int(int, int)类型的
    
    /*
    我们能够定义一个map,用string类型来关联对应的函数,用string作为标识
    */
    void fun11()
    {
        auto mod=[](int i, int j){return i%j;};
        map<string, int(*)(int, int)> binops;   //这是一个函数指针,返回一个int类型
        //这里add是一个指向+运算的指针,div是不能这样加的,它不是指针
        binops.insert({"+", add});
        binops.insert({"%", mod});
    //    binops.insert({"/", div2});
    }
    
    /**
    库函数类型
    */
    void fun12()
    {
        function<int(int, int)> f1=add;     //函数指针,这个是加法
        function<int(int, int)> f2=div2();   //调用()操作符,这个是除法
        function<int(int, int)> f3=[](int i, int j) {return i*j;};  //lambda返回乘法
        cout<<f1(4,2)<<endl;    //6
        cout<<f2(4,2)<<endl;    //2
        cout<<f3(4,2)<<endl;    //8
    }
    
    void fun13()
    {
        auto mod=[](int i, int j){return i%j;};
        map<string, function<int(int, int)>> binops=
        {
            {"+", add},{"-", std::minus<int>()},{"/", div2()},{"*", [](int i, int j){return i*j;}},
            {"%", mod}
        };  //这个map有五个元素,当我们索引这个map的时候,我们能够调用这五个函数类型
    
        cout<<"+ <--->"<<binops["+"](10, 5)<<endl;
        cout<<"- <--->"<<binops["-"](10, 5)<<endl;
        cout<<"/ <--->"<<binops["/"](10, 5)<<endl;
        cout<<"* <--->"<<binops["*"](10, 5)<<endl;
        cout<<"% <--->"<<binops["%"](10, 5)<<endl;
    }
    
    /**
    Overloaded Functions and function
    重载的函数和功能
    */
    void fun14()
    {
        map<string, function<int(int, int)>> binops;
        int (*fp)(int, int)=add;
        binops.insert({"+", fp});   //用函数指针来避免重载,或者同名函数的含糊不清
        //含有一个非常好的办法就是使用lambda来消除歧义是非常好的
        binops.insert({"+", [](int a, int b){return add(a,b);}});
    
    }
    
    /*
    在新的库函数类是不相关的类命名为
    unary_function和binary_function是较早的版本号的一部分
    标准库。这些类被更一般的结合使用函数代替
    */
    
    int main()
    {
        cout<<">>----------------fun1---------------------<<"<<endl;
        fun1();
        cout<<">>----------------fun2---------------------<<"<<endl;
        fun2();
        cout<<">>----------------fun3---------------------<<"<<endl;
        fun3();
        cout<<">>----------------fun4---------------------<<"<<endl;
        fun4();
        cout<<">>----------------fun5---------------------<<"<<endl;
        fun5();
        cout<<">>----------------fun6---------------------<<"<<endl;
        fun6();
        cout<<">>----------------fun7---------------------<<"<<endl;
        fun7();
        cout<<">>----------------fun8---------------------<<"<<endl;
        fun8();
        cout<<">>----------------fun9---------------------<<"<<endl;
        fun9();
        cout<<">>----------------fun12---------------------<<"<<endl;
        fun12();
        cout<<">>----------------fun13---------------------<<"<<endl;
        fun13();
    
        system("pause");
        return 0;
    }
    

    PS:今天早上有点晚了,不行,以后每天早上坚持至少8点開始,7点起床!!!努力,我要学的东西还非常多,远远不够,时间如此紧迫,怎可徒费光阴!!!




  • 相关阅读:
    nginx:font-awesome图标刷新后显示不了
    nginx:用openssl生成证书
    安全:http host头攻击漏洞
    js:获得屏幕的宽高
    java中URLEncode与Delphi中关系
    Error during WebSocket handshake: Unexpected response code: 404
    byte数组与MultipartFile相互转化
    Java字符串或数组去掉前后的中括号标签
    IDEA运行新项目时报 Error running ‘XXApplication‘: Command line is too long. Shorten command line for…… 错误
    (转)ElasticSearch中"distinct","count"和"group by"的实现
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4029480.html
Copyright © 2020-2023  润新知