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

来源:互联网 发布:数据库发展历史 编辑:程序博客网 时间:2024/06/14 23:25

函数引用操作符

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, '\n'); //上面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, '\n'));    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<<"\t";}


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<<"\t";    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<<"\t";});}

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

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)<<"\t";}


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, '\n'); //上面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, '\n'));    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<<"\t";}/**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<<"\t";    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<<"\t";});}//通过指针直接操作内存的地址,来改变排序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)<<"\t";}/**************************************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点起床!!!努力,我要学的东西还很多,远远不够,时间如此紧迫,怎可徒费光阴!!!




0 0
原创粉丝点击