首页 > 代码库 > 【足迹C++primer】48、函数引用操作符
【足迹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, '\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 Algorithmsvoid 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点起床!!!努力,我要学的东西还很多,远远不够,时间如此紧迫,怎可徒费光阴!!!
【足迹C++primer】48、函数引用操作符
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。