仿函数及其应用
作者:互联网
-
仿函数(functor)
仿函数的概念与作用
在我们写代码时有时会发现有些功能实现的代码,会不断的在不同的成员函数中用到,但是又不好将这些代码独立出来成为一个类的一个成员函数。但是又很想复用这些代码。写一个公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。这时就可以用仿函数了,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。这样就免去了对一些公共变量的全局化的维护了。又可以使那些代码独立出来,以便下次复用。而且这些仿函数,还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了)。如果在配合上模板技术和policy编程思想,那就更是威力无穷了,大家可以慢慢的体会。 有时仿函数的使用是为了函数拥有类的性质,以达到安全传递函数指针,依据函数生成对象,甚至是让函数之间有继承关系,对函数进行运算和操作的效果。比如set就使用了仿函数less ,而less继承的binary_function,就可以看作是对于一类函数的总体声明了,这是函数做不到的。1 2 3 4 5 6 7 8 9 |
//less的定义
template < typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool >
{
bool
operator()( const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
|
1 2 3 4 |
//set的定义
template < typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class set;
|
仿函数在各编程语言中的范例
C语言使用函数指针和回调函数来实现仿函数,例如一个用来排序的函数可以这样使用仿函数#include <stdlib.h> /* Callback function */ int compare_ints_function(void*A,void*B) { return*((int*)(A))<*((int*)(B)); } /* Declaration of C sorting function */ void sort(void*first_item,size_t item_size,void*last_item,int(*cmpfunc)(void*,void*)); int main(void) { int items[]={4,3,1,2}; sort((void*)(items),sizeof(int),(void*)(items +3), compare_ints_function); return 0; }
C++
在C++里,我们通过在一个类中重载括号运算符的方法使用一个函数对象而不是一个普通函数。class compare_class{ public: bool operator()(int A, int B)const{return A < B;} }; // Declaration of C++ sorting function. template<class ComparisonFunctor> void sort_ints(int* begin_items, int num_items, ComparisonFunctor c); int main(){ int items[]={4, 3, 1, 2}; compare_class functor; sort_ints(items, sizeof(items)/sizeof(items[0]), functor); }
C#
C#是通过委托(delegate)来实现仿函数的。Java
Java中的仿函数是通过实现包含单个函数的接口实现的List<String> list =Arrays.asList("10", "1", "20", "11", "21", "12"); Comparator<String> numStringComparator =new Comparator<String>(){ publicint compare(String o1, String o2){ returnInteger.valueOf(o1).compareTo(Integer.valueOf(o2)); } }; Collections.sort(list, numStringComparator);
仿函数的实际应用C++
编辑#include <iostream> #include <algorithm> #include <cstdio> #include <ctime> #include <cstring> #include <string> #include <set> typedef long long LL; class Prt{ char c[53]; int top; public: template <class T> Prt& operator()(T x); Prt& operator()(LL x); Prt& operator()(int x); Prt& operator()(char x); Prt& operator()(const char*x); Prt& operator()(double x); Prt& operator()(const std::string x); Prt& operator()(double x,int k){ sprintf(c,"%%.%dlf",k); printf(c,x); return *this; } }; template <typename T> Prt& Prt::operator()(T x){ std::cout<<x; return *this; } Prt& Prt::operator()(LL x){ if(x==0){ putchar('0'); return *this; } if(x<0){ putchar('-'); x=-x; } top=0; while(x>0){ c[top++]='0'+x%10; x/=10; } while(top--){ putchar(c[top]); } return *this; } Prt& Prt::operator()(int x){ return operator()((LL)(x)); } Prt& Prt::operator()(char x){ putchar(x); return *this; } Prt& Prt::operator()(const char*x){ printf("%s",x); return *this; } Prt& Prt::operator()(double x){ printf("%lf",x); return *this; } Prt& Prt::operator()(const std::string x){ return operator()(x.data()); } Prt prt; struct st{int x,y;st(){x=y=0;}st(int a,int b){x=a;y=b;}}; std::ostream& operator<<(std::ostream& fout,const st&x){ fout<<"["<<x.x<<","<<x.y<<"]"; return fout; } int main(){ prt(">>> prt(\"LL:\")(12341231234123ll)(\' \')(\"int:\")(15)(\'\\n\');\n"); prt("LL:")(12341231234123ll)(' ')("int:")(15)('\n'); prt('\n'); prt(">>> prt(\"char:\")(\'a\')(\" char*(/string):\")(std::string(\"abc\"))(\" d \")\ ((std::string(\"abc\")).data())(\'\\n\');\n"); prt("char:")('a')(" char*(/string):")(std::string("abc"))(" d ") ((std::string("abc")).data())('\n'); prt('\n'); prt(">>> prt(\"double:\")(1.5)(\" double[int]:\")(10.12349746192736,4)(\'\\n\');\n"); prt("double:")(1.5)(" double[int]:")(10.12349746192736,4)('\n'); prt("\n>>> prt(st(12,31));\n"); prt(st(12,31)); prt('\n'); return 0; }
这里放一下输出,这样的安排主要是为了突出代码效果 >>> prt("LL:")(12341231234123ll)(' ')("int:")(15)('\n'); LL:12341231234123 int:15 >>> prt("char:")('a')(" char*(/string):")(std::string("abc"))(" d ")((std::string("abc")).data())('\n'); char:a char*(/string):abc d abc >>> prt("double:")(1.5)(" double[int]:")(10.12349746192736,4)('\n'); double:1.500000 double[int]:10.1235 >>> prt(st(12,31)); [12,31]
标签:函数,prt,int,及其,char,Prt,应用,operator 来源: https://www.cnblogs.com/xietianjiao/p/12344086.html