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


    原文:http://blog.csdn.net/tianshuai1111/article/details/7687983

    一,概述
            仿函数(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
    ", 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>

  • 相关阅读:
    ADO.NET 2.调用存储过程
    Resharper上手指南
    获取HTML源码(只取文字,判断编码,过滤标签)
    .net(c#) winform文本框只能输入数字,不能其他非法字符(转)
    ADO.NET – 3.书籍管理系统详解
    GemBox.ExcelLite.dll导出到Excel
    C#4.0图解教程 第7章 类和继承
    C#读取网站HTML内容
    C#回顾 – 1.IO文件操作
    Javascript s10 (Jquery相关手册整合及功能实现)
  • 原文地址:https://www.cnblogs.com/Leo-Forest/p/3894300.html
Copyright © 2020-2023  润新知