zoukankan      html  css  js  c++  java
  • C++ lambda表达式、function、bind用法

    工程上来说如果要在类里面添加一个“行为”, 可能要经过好多步编码操作。

    比如对于某一类A , update函数里要调用一堆同类函数,这些函数还要初始化等等的操作.需要编写大量代码,对我等懒人来说真是麻烦死了。例如如下类A

    A.h

     1 class A
     2 {
     3 public:
     4     A();
     5     ~A();
     6     void update();
     7 private:
     8     bool fun1();
     9     bool fun2();
    10     bool fun3();
    11 
    12     void run(const string& s);
    13 }

    比如想在A中的update函数里调用fun1()~funN(), 如果返回true则执行run:

    if(fun1()){
    	run("fun1");
    }
    
    if(fun2()){
    	run("fun2");
    }
    
    if(fun3()){
    	run("fun3");
    }
    

      当然你可以不厌其烦地写N个类,每个类有fun和run 然后用基类+多态实现。这里只说懒人用法。我在A里添加一个vector,把所有function都遍历一下就搞定了:

    class A
    {
    public:
        struct CALL{
            function<bool(void)> func;
            string name;
        };
    
        A();
        ~A();
        void update();
    private:
    
        vector<CALL> cache;
    
        bool fun1();
        bool fun2();
        bool fun3();
    
        void run(const string& s);
    }
     1 A::A()
     2 {
     3     CALL f1,f2,f3;
     4     f1.name = "fun1";
     5     f2.name = "fun2";
     6     f3.name = "fun3";
     7 
     8     f1.func = bind(&A::fun1, this);
     9     f2.func = bind(&A::fun2, this);
    10     f3.func = bind(&A::fun3, this);
    11 }
    12 
    13 void A::update()
    14 {
    15     for(vector<CALL>::iterator itr = cache.begin(); itr != cache.end(); itr++)
    16     {
    17         if(itr->func()){
    18             run(itr->name);
    19         }
    20     }
    21 }

    但是这样一来,每次要新增一个funX就要写两行CALL结构初始化、还要在CLASS里添加函数funX. 对我这种懒人来说代码量还需要减少75%才愿意动手。lambda表达式的优势在这时体现出来了:

     1 #include<vector>
     2 #include<functional>
     3 using namespace std;
     4 
     5 class A
     6 {
     7 public:
     8     struct CALL{
     9         function<bool(void)> func;
    10         string name;
    11     };
    12 
    13     A();
    14     ~A();
    15     void update();
    16 private:
    17 
    18     vector<CALL> cache;
    19 
    20     void run(const string& s);
    21 }
    A::A()
    {
        CALL call[3];
        int i;
        for(i=0;i<3;++i)
        {
            char str[10];
            sprintf(str, "fun%d", i+1);
            call[i].name = string(str);
        }
        call[0] = [](){
            bool ret
            ...;
            return ret;
        };
        call[1] = [](){
            bool ret
            ...;
            return ret;
        };
        call[2] = [](){
            bool ret
            ...;
            return ret;
        }
    }
    
    void A::update()
    {
        for(vector<CALl>::iterator itr = cache.begin(); itr != cache.end(); itr++)
        {
            if(itr->func()){
                run(itr->name);
            }
        }
    }

    此后要加任何函数只要直接写,不用继承多态,俗语曰随便搞。

    优势:代码少、代码即文档、产品随便加减需求、无效率问题

      

    除非注明,Cydonia博客文章均为原创,转载请以链接形式标明本文地址

      

    博客地址:http://www.cnblogs.com/cydonia/

  • 相关阅读:
    C# dynamic使用
    Linq简介二
    遇事处理方式
    为什么select关键字没有放到前面而是放到了后面
    decimal、float、double区别
    ViewBag、ViewData、TempData区别
    CommandBehavior.CloseConnection的使用
    LINQ简介一
    ViewBag、ViewData使用
    SQL Server 使用WriteText 存储大容量数据
  • 原文地址:https://www.cnblogs.com/cydonia/p/Cydonia.html
Copyright © 2011-2022 走看看