zoukankan      html  css  js  c++  java
  • c++11 function bind 测试。

    实验小结

    1)function 是一个模板类。有函数指针成员。可以看作安全型函数指针。

    template<typename _Res, typename... _ArgTypes> 
    class function<_Res(_ArgTypes...)> : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,private _Function_base{

    private:

    typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);

    _Invoker_type _M_invoker;

    }

    2)空function。调用会抛出异常。

    3)可以接受普通函数、Lambda表达式、函数指针、以及其它函数对象。

    并可以把防函数为参数构成的function对象传递给一个函数指针。而放函数是不能直接给函数指针的。

     4)bind 猜测是根据一个函数声明,转为一个防函数。好处就是放函数本质是一个类。可以保存数据成员。达到一些其他目的。

    5)bind 使用placeholder这些是重载函数的参数。没有占位,而直接输入的是函数的数据成员。这样bind就可以返回一个防函数的对象了。

    6)而function是可以接受放函数的。当然也可以接受bind的返回值了。

     7)bind加上function。就可以让一个函数转换为一个放函数对象,并转为function类型。而function类型的特性。可以放到任何需要函数指针的地方。完美!

    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    using namespace std;
    
    
    bool big5(int a)
    {
        if(a>5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    int GreaterInt(vector<int>::const_iterator start,vector<int>::const_iterator end,int compareInt)
    {
        int ret=0;
        for(start; start!=end; ++start)
        {
            if(*start>compareInt)
            {
                ++ret;
            }
        }
        return ret;
    }
    
    int LessInt(vector<int>::const_iterator start,vector<int>::const_iterator end,int compareInt)
    {
        int ret=0;
        for(start; start!=end; ++start)
        {
            if(*start<compareInt)
            {
                ++ret;
            }
        }
        return ret;
    }
    
    int ComplexLogic(vector<int>::const_iterator start,vector<int>::const_iterator end)
    {
        int ret=0;
        for(start; start!=end; ++start)
        {
            if(*start>5&&*start!=8)
            {
                ++ret;
            }
        }
        return ret;
    }
    
    typedef bool(* FunMycompare)(int);
    bool ComplexLogic2(int value);
    template<typename T>
    int Count_bool(vector<int>::const_iterator start,vector<int>::const_iterator end,T myfun)
    {
        int ret=0;
        for(start; start!=end; ++start)
        {
            if(myfun(*start))
            {
                ++ret;
            }
        }
        return ret;
    }
    
    int Count_bool2(vector<int>::const_iterator start,vector<int>::const_iterator end,FunMycompare myfun)
    {
        int ret=0;
        for(start; start!=end; ++start)
        {
            if(myfun(*start))
            {
                ++ret;
            }
        }
        return ret;
    }
    
    bool Greater5(int value)
    {
        if(value>5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool GreaterSmart(int value,int value2)
    {
        if(value>value2)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool Less5(int value)
    {
        if(value<5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    //函数指针重载问题.改名
    bool ComplexLogic2(int value)
    {
        if(value>5&&value!=8)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool errorLess5(int value,int abc)
    {
        if(abc<5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    class GreaterFactor
    {
    public:
        GreaterFactor(int value):compareInt(value) {}
        bool operator()(int value)
        {
            if(value>compareInt)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        int compareInt;
    };
    
    
    int main()
    {
        vector<int> intContainer;
        for (int i = 1; i <= 10; ++i)
        {
            intContainer.push_back(i);
        }
        cout<<"*********normal funtions ****************************";
        // 查找元素值大于某值的元素的个数
        cout<<GreaterInt(intContainer.begin(),intContainer.end(),5)<<endl;
    
        // 查找元素值小于某值的元素的个数
        cout<<LessInt(intContainer.begin(),intContainer.end(),5)<<endl;
    
        // 查找元素值大于5,且不等于8个数
        cout<<ComplexLogic(intContainer.begin(),intContainer.end())<<endl;
    
    
        //问题来了.针对元素,求bool值的需求,越来越多. >=,<= >,< !=,=..甚至是什么比如>5&&!=8,等一些逻辑组合.
        //这里因为函数代码不多,当然每个需求都写一个方法没什么大问题.
        //但这些函数可以发现有共同的代码.就是遍历逻辑.假设这里不是遍历而是一个非常复杂的代码段,而且会有改动的情况.
        //所以只要这个逻辑有改动的时候,就需要在所有的函数中修改,就非常辛苦和容易出错.
        //所以,首先反应是,保留相同逻辑代码.把不同的逻辑代码找出来,用抽象接口代替,
        //c++的抽象接口方式,还是c的函数指针.
        //这里抽象为的函数原型为:typedef bool(* FunMycompare)(int);
        //因为需求太多,有2参,有3参,或者更多.所以干脆,抽象为1参,也就是值保留了遍历元素时,元素本身的值.
    
        cout<<"******************call back()********************************************"<<endl;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),Greater5)<<endl;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),Less5)<<endl;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),ComplexLogic2)<<endl;
    
        //好处有了,就是隔离了变化.有新的需求.就只要写一个bool函数就好了.把函数名当作函数指针作为算法Count_bool的参数.
        //但Greater5明显没有之前的GreaterInt好用,
        //有一个防函数的东西.配合模板,刚好可以用到这里.就是对一个类重载,他的实例使用()符号的逻辑.让一个对象可以有,obj(a,b)这样像函数一样的操作.对象行为像函数指针.
        //而类可以有成员数据.所以初始化的时候,可以把必要数据存储.再想想有什么替代办法.
        //实在不喜欢操作符重载.别的语言是越来越直观,c++感觉基础操作就设置了太多坑.简洁但不能让人误解和性能不降低,否则这简洁没意思.
    
        //要把int Count_bool(vector<int>::const_iterator start,vector<int>::const_iterator end,T myfun)改为模板.才能不在乎你是函数指针还是防函数.
        //因为模板是代码生成器,会为不同那个的参数类型,静态生成各自的代码.
        //cout<<Count_bool(intContainer.begin(),intContainer.end(),GreaterFactor(8))<<endl;
    
    
        cout<<"******************call back(error convertion & test fun)********************************************"<<endl;
        //强转造成类型不安全.
        cout<<Count_bool(intContainer.begin(),intContainer.end(),(FunMycompare)errorLess5)<<endl;
        //但是修改为模板也可以强转啊.
    
        //看下functional
    
    //template<typename _Res, typename... _ArgTypes>
    //    class function<_Res(_ArgTypes...)>
    //    : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
    //      private _Function_base
    //    {
    
    
        //    private:
    //      typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
    //      _Invoker_type _M_invoker;
    //    return 0;
        //其实就是定义了一个函数指针类型.跟原来的 typedef bool(* FunMycompare)(int); 是一样的.
        typedef function<bool(int)> FunMycompareSafe;
        FunMycompareSafe safeGreater5=Greater5;
    
        //测试一下,ok.
        cout<<Count_bool(intContainer.begin(),intContainer.end(),safeGreater5)<<endl;
        //在测试一下强壮.
        FunMycompareSafe safeErrorGreater5=(FunMycompare)errorLess5;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),safeErrorGreater5)<<endl;
        //...没看出来function的安全在哪里.强转也还是可以编译通过.这个....
        //应该是强转就已经转为了合法的原型.所以function无法判断.那么原来的函数指针不安全到底在哪里?
        //空指针?测试一下.
    
        //o.这里编译通过.但运行是肯定出错.
    
        //类型安全个鬼啊.只是抛出了异常而已.不是编译期安全.
    //    FunMycompare emptyPFun=0;
    //    try
    //    {
    //        cout<<Count_bool(intContainer.begin(),intContainer.end(),emptyPFun)<<endl;
    //    }
    //    catch(exception& e)
    //    {
    //        cout<<e.what()<<endl;
    //    }
    
        FunMycompareSafe emptyPfun2=0;
        try
        {
           cout<<Count_bool(intContainer.begin(),intContainer.end(),emptyPfun2)<<endl;
        }
        catch(exception& e)
        {
            cout<<e.what()<<endl;
        }
    
        cout<<"functional***pointer of funtion******************************"<<endl;
        function<bool(int)> ill_safeGreater5=Greater5;
        function<bool(int)> ill_safeLess5=Less5;
        function<bool(int)> ill_safeComplexLogic=ComplexLogic2;
    
        cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeGreater5)<<endl;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeLess5)<<endl;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeComplexLogic)<<endl;
    
        cout<<"*****class function******************************"<<endl;
        GreaterFactor goodFun=GreaterFactor(7);
    
        //方法模板可以接受防函数.
        cout<<Count_bool(intContainer.begin(),intContainer.end(),goodFun)<<endl;
    
        //error,强类型普通方法,不接受方函数.类型不一致.
        //cout<<Count_bool2(intContainer.begin(),intContainer.end(),goodFun)<<endl;
    
        //强类型普通方法,接受function 对象.就像funtion的实参是一个方函数.
        function<bool(int)> testclassfun=goodFun;
        cout<<Count_bool(intContainer.begin(),intContainer.end(),testclassfun)<<endl;
    
        //o~~~~, function 的特性终于体现出来了.可以装载防函数.
        //并且可以把防函数转为普通的函数指针.
    
        //没有仔细看bind的大概实现.主要作用,可以不用手工写一个仿函数了.
        //推测大概作用就是生成一个仿函数的对象.
        //就是把一个函数变成方函数,占位符就是防函数的重载括号内的参数,而输入的值就是方函数的数据成员.
        //猜测bind返回一个方函数.而function是可以接受一个方函数的.所以bind可以给function.
        //因为function.可以直接给函数指针.
        auto bindfunc1=bind(GreaterSmart,placeholders::_1,9);
        function<bool(int)> testclassfun22=bindfunc1;
        cout<<Count_bool2(intContainer.begin(),intContainer.end(),bindfunc1)<<endl;
    
    
    
    }
  • 相关阅读:
    SVM学习笔记-线性支撑向量机
    阿里面试回来,想和Java程序员谈一谈
    看外国女程序员如何直播写代码
    shoeBox超实用的雪碧图(Sprite)图制作工具-使用
    Android图像处理之图形特效处理
    SMP、NUMA、MPP体系结构介绍
    TIOBE 2017 8月编程语言排行榜 后院“硝烟四起”
    Android Studio中Git和GitHub使用详解
    矩阵乘法快速幂 codevs 1574 广义斐波那契数列
    矩阵乘法 codevs 1287 矩阵乘法
  • 原文地址:https://www.cnblogs.com/lsfv/p/6255696.html
Copyright © 2011-2022 走看看