• 【C++ STL】深入解析神秘的 仿函数


    一,概述
            仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
      有些功能的的代码,会在不同的成员函数中用到,想复用这些代码。

                                1)公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。

                                2)仿函数,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。


    二,仿函数(functor)在各编程语言中的应用

      1)C语言使用函数指针回调函数来实现仿函数,例如一个用来排序的函数可以这样使用仿函数
      

    #include <stdio.h>
    #include <stdlib.h>
    //int sort_function( const void *a, const void *b);
    int sort_function( const void *a, const void *b)
    {   
    	return *(int*)a-*(int*)b;
    }
    
    int main()
    {
       
       int list[5] = { 54, 21, 11, 67, 22 };
       qsort((void *)list, 5, sizeof(list[0]), sort_function);//起始地址,个数,元素大小,回调函数 
       int  x;
       for (x = 0; x < 5; x++)
    		  printf("%i\n", list[x]);
    			      
       return 0;
    }
    

            2)在C++里,我们通过在一个类中重载括号运算符的方法使用一个函数对象而不是一个普通函数。

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    template<typename T>
    class display
    {
    public:
    	void operator()(const T &x)
    	{
    		cout<<x<<" "; 
    	} 
    }; 
    
    
    int main()
    {
    	int ia[]={1,2,3,4,5};
    	for_each(ia,ia+5,display<int>()); 
    	
    	return 0; 
    } 


    三,仿函数在STL中的定义

            要使用STL内建的仿函数,必须包含<functional>头文件。而头文件中包含的仿函数分类包括

             1)算术类仿函数

                   加:plus<T>

                   减:minus<T>

                   乘:multiplies<T>

                   除:divides<T>

                   模取:modulus<T>

                   否定:negate<T>

    例子:

    #include <iostream>
    #include <numeric>
    #include <vector> 
    #include <functional> 
    using namespace std;
    
    int main()
    {
    	int ia[]={1,2,3,4,5};
    	vector<int> iv(ia,ia+5);
    	cout<<accumulate(iv.begin(),iv.end(),1,multiplies<int>())<<endl; 
    	
    	cout<<multiplies<int>()(3,5)<<endl;
    	
    	modulus<int>  modulusObj;
    	cout<<modulusObj(3,5)<<endl; // 3 
    	return 0; 
    } 


             2)关系运算类仿函数

                   等于:equal_to<T>

                   不等于:not_equal_to<T>

                   大于:greater<T>

                   大于等于:greater_equal<T>

                   小于:less<T>

                   小于等于:less_equal<T>

                  从大到小排序:

    #include <iostream>
    #include <algorithm>
    #include <vector> 
    
    using namespace std;
    
    template <class T> 
    class display
    {
    public:
    	void operator()(const T &x)
    	{
    		cout<<x<<" "; 
    	} 
    };
    
    int main()
    {
    	int ia[]={1,5,4,3,2};
    	vector<int> iv(ia,ia+5);
        sort(iv.begin(),iv.end(),greater<int>());
    	for_each(iv.begin(),iv.end(),display<int>()); 
    	return 0; 
    } 

                3)逻辑运算仿函数

                     逻辑与:logical_and<T>

                     逻辑或:logical_or<T>

                     逻辑否:logical_no<T>



  • 相关阅读:

    HTTP请求和响应格式
    什么是Alpha,Beta,RC,RTM,CTP版
    GE的分级体系与卫片的分辨率关系
    如何下载这幅DigitalGlobe卫星图?
    Google Maps/Earth下载图片封IP的最佳解决方法
    MAPGIS把经纬度坐标转换为大地坐标
    从Google卫星地图服务器上获取卫星照片的方法收藏
    谷歌地球 GoogleEarth软件介绍
    Oracle 查找表的字段信息
  • 原文地址:https://www.cnblogs.com/secbook/p/2654987.html
Copyright © 2020-2023  润新知