STL基础--仿函数(函数对象)
发布时间:2020-12-14 05:17:33 所属栏目:大数据 来源:网络整理
导读:1 首先看个仿函数的例子 class X { public: void operator()(string str) { // 函数调用运算符,返回类型在operator之前 cout "Calling functor X with parameter " str endl; } operator string () const { return "X"; } //类型转换函数,返回类型在operat
1 首先看个仿函数的例子class X { public: void operator()(string str) { // 函数调用运算符,返回类型在operator之前 cout << "Calling functor X with parameter " << str<< endl; } operator string () const { return "X"; } //类型转换函数,返回类型在operator之后 }; int main() { X foo; foo("Hi"); // 以参数HI调用仿函数X } /* * 仿函数的好处: * 1. 智能函数: 比常规函数有更多的功能,比如可以保存状态(参数化的函数) * 2. 有它自己的类型,不用考虑函数重名问题 * 事实上,类带来的其他好处,封装,继承,多态都可以是仿函数的好处 */ 2 参数化的函数class X { public: X(int i) {} void operator()(string str) { cout << "Calling functor X with parameter " << str<< endl; } }; int main() { X(8)("Hi"); } // 为什么需要参数化函数,用2个参数的函数代替不行么? // 只实现+2的功能,如果我想实现加任何数的功能 void add2(int i) { cout << i+2 << endl; } // 用全局变量,显然不好 // 用模板实现,加任何值的功能,但是val需要编译时常数 template<int val> void addVal(int i) { cout << val+i << endl; } // 轮到仿函数登场了 class AddValue { int val; public: AddValue(int j) : val(j) { } void operator()(int i) { cout << i+val << endl; } }; int main() { vector<int> vec = { 2,3,4,5}; //for_each(vec.begin(),vec.end(),add2); // {4,5,6,7} int x = 2; //for_each(vec.begin(),addVal<x>); // {4,7} ,编译不过 for_each(vec.begin(),AddValue(x)); // {4,7} } 3 内置的仿函数// 比较 less greater greater_equal less_equal not_equal_to // 逻辑 logical_and logical_not logical_or // 算术 multiplies minus plus divide modulus negate int x = multiplies<int>()(3,4); // x = 3 * 4 if (not_equal_to<int>()(x,10)) // if (x != 10) cout << x << endl; 4 参数绑定set<int> myset = { 2,5}; vector<int> vec; int x = multiplies<int>()(3,4); // x = 3 * 4 // 将元素值乘以10,保存在vec中: transform(myset.begin(),myset.end(),// 源 back_inserter(vec),// 目的 bind(multiplies<int>(),placeholders::_1,10)); // 仿函数 // multiplies<int>()的第1个参数替换为myset中的元素值 // vec: {20,30,40,50} void addVal(int i,int val) { cout << i+val << endl; } for_each(vec.begin(),bind(addVal,2)); // C++ 03: bind1st,bind2nd 5 将常规函数转为仿函数double Pow(double x,double y) { return pow(x,y); } int main() { set<int> myset = {3,1,25,7,12}; deque<int> d; auto f = function<double (double,double)>(Pow); //C++ 11 transform(myset.begin(),// 源地址 back_inserter(d),// 目的 bind(f,2)); // 仿函数 // d: {1,9,49,144,625} } // C++ 03中使用ptr_fun 6 lambda函数// 想拷贝5<x<20之间的元素到d set<int> myset = {3,12}; deque<int> d; // 定义一个函数 bool needCopy(int x){ return (x>20)||(x<5); } // 或者用内置仿函数和bind结合 // 两种方法都不方便 transform(myset.begin(),// source back_inserter(d),// destination needCopy ); /* bind(logical_or<bool>,bind(greater<int>(),20),bind(less<int>(),5)) */ // C++ 11 lambda function: transform(myset.begin(),// destination [](int x){return (x>20)||(x<5);} //lambda函数 ); 7 为什么STL中需要仿函数?set<int> myset = {3,12}; // myset: {1,12,25} // 同: set<int,less<int> > myset = {3,12}; bool lsb_less(int x,int y) { return (x%10)<(y%10); } class Lsb_less { public: bool operator()(int x,int y) { return (x%10)<(y%10); } }; int main() { set<int,Lsb_less> myset = {3,12}; // myset: {1,7} ... } 8 谓词/* * 一种特殊的仿函数: * 1. 返回一个boolean值 * 2. 不改变数据 */ class NeedCopy { bool operator()(int x){ return (x>20)||(x<5); } }; transform(myset.begin(),// destination NeedCopy() ); // 谓词用于比较或者条件判断 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |