首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

使用boost的函数库实现通用switch-case/if.else选择器,该怎么处理

2012-02-20 
使用boost的函数库实现通用switch-case/if..else选择器在通信行业做事久了,经常发现在写的程序中,大量重复

使用boost的函数库实现通用switch-case/if..else选择器
在通信行业做事久了,经常发现在写的程序中,大量重复出现if..else..这种嵌套层次相当深的switch写法,所以就蒙生了自己写一个通用switcher的想法,把这种强耦合的写法隔离,所以就用了下面的实现

/*********************************************
  *                     通用选择器
  *     1.   适配原始函数指针
  *     2.   适配成员函数指针
  *     3.   适配仿函数
  *     4.   绑定函数
  ********************************************/
template <typename   RESULT,
                  typename   KEY,
                  typename   PARA>
class   switcher
{
private:
        typedef   boost::function <RESULT,   PARA>   FUNCTOR;
public:
        void   add_observer(KEY   key,   FUNCTOR   func)
        {
                functorset.insert(make_pair(key,   func));
        }
       
        RESULT   match(KEY   key,   PARA   para)
        {
                map <KEY,   FUNCTOR> ::const_iterator   iter;
                iter   =   functorset.find(key);
                if   (iter   !=   functorset.end())
                {
                        static_cast <FUNCTOR> (iter-> second)(para);
                }
        }
private:        
        map <KEY,   FUNCTOR>   functorset;                      
};

bool   some_function(const   std::string&   s)  
{
        std::cout   < <   s   < <   "   This   is   really   neat\n ";
        return   true;
}

class   some_class  
{
public:
        bool   some_function(const   std::string&   s)  
        {
                std::cout   < <   s   < <   "   This   is   also   quite   nice\n ";
                return   true;
        }
};
class   some_function_object  
{
public:
        bool   operator()(const   std::string&   s)  
        {
                std::cout   < <   s   < <
                "   This   should   work,   too,   in   a   flexible   solution\n ";
                return   true;
        }
};

switcher <bool,   int,   string>   myswitcher;



bool   test(int   number,   string   info)
{
        return   myswitcher.match(number,   info);
}

int   main(int   argv,   char**   argc)
{
        function1 <bool,const   std::string&>   f1(&some_function);
        function1 <bool,const   std::string&>   f2(&some_class::some_function,&s);
        function1 <bool,const   std::string&>   f3(boost::bind(&some_class::some_function,&s,_1));
        some_function_object   fso;
        function1 <bool,const   std::string&>   f4(fso);
        myswitcher.add_observer(0,   f1);
        myswitcher.add_observer(1,   f2);
        myswitcher.add_observer(2,   f3);
        myswitcher.add_observer(3,   f4);
        test(0,   "call   by   f1 ");
}

文章还有不足之处,敬请大家指教,希望能和喜欢Boost库的朋友做做交流


[解决办法]
这个,需要做这么复杂吗?
switch用查表法实现是个基本常识,直接用map + boost的assign库map_list_of已经足够了。

[解决办法]
是哦.要么LZ谈谈, 相对比state, strategy模式有什么优势.
[解决办法]
如楼上所说,用表驱动的状态机来表示,代码只会变短。
[解决办法]
既然你用了状态机就应该明白它的表驱动表示法撒。
Map的算法效率是O(LogN),查表法可以是O(1),哪个效率好?
Map的绑定关系是一维的,而查表法是二维的,从逻辑上更为清晰,特别是使用嵌套状态的时候。
[解决办法]
局部代码乱,可以用重构的方法整理。整体代码乱,还不如推倒重来。

而且我觉得一开始就用Boost不是什么明智之举,与效率、维护都没什么直接关系。
[解决办法]
为什么忽视vtbl呢? C++自身就有表啊.

为什么忽视 < <设计模式> > 里的state, strategy模式这些模式呀?

我预计你们的方案一定是有更高的运行时效率 ? 有更好的扩展性 ?

解释下.谢谢.
[解决办法]
有bug

1. 没有返回值:
2. find()失败, 直接崩溃!

RESULT match(KEY key, PARA para)
{
map <KEY, FUNCTOR> ::const_iterator iter;
iter = functorset.find(key);
if (iter != functorset.end())
{
static_cast <FUNCTOR> (iter-> second)(para);
}
}

[解决办法]
好了. 大家没啥火气了, 再好好聊聊吧.

说实在的. 我觉得你这个类, 做做练习, 锻炼一下是挺好的. 但我不会将他作为正式的工程项目中的一部分.

1. 没有严格验证.
2. 相对来说比较复杂. 他要求项目组里的人要会用boost::function, boost::bind. 这个在当前有点要求过高.
3. 实现的效率不高. map的复杂度, 正如 BluntBlade 所说, O(logN), 比起O(1).效率低. 不过, 再怎么说, 这个case 不可能上百万条吧, 所以效率也许不在热点上也不是问题.
4. 只支持 单参 方法, 还不支持 返回值. 我有点接受不了. 不知道boost::signal怎么搞的.要研究呀.
5. 我们总是忽略惯用手法和成熟经验. 这在我的公司尤其如此, 过分强调创新, 忽略这样的事实, 成功的项目往往取决于采用的成熟库在整体代码中占的比重. 这也是我一看到这么个新东西的反感. 向你道个歉.
6. 面向对象的设计模式是反复应用反复实践的成熟理论. 并且, 当前有重构, 迭代这样的成熟工程理论支撑确保能小步走向目标. 因此, 相对而言, 我愿意采取这样的技术.
7. 我喜欢范型, 也愿意学习它, 但目前看下来在真实的项目中, 大规模实行, 目前还没有到时候.这要求一个团队的软件成熟度达到一定的层次才行的. 不压抑自己的技术欲望, 盲目的优化, 采用新技术, 给项目带来多少血的教训啊. 我自己也深有体会. 因此, 我常要清醒下自己, 切莫满负荷, 保持掌握里.

乱写一气, 莫怪~
[解决办法]
此帖收藏。。。

向楼上的牛人们学习。。。

弱弱的问一下, 楼上的牛牛们工作几年了 ??? 学习.....
------解决方案--------------------


第二点,什么是强侵入性设计。
强侵入性设计是指对使用者有很多要求,即使很多功能用户不需要使用也无法裁减和替代。
MFC已经被认为是强侵入性设计的典范,而ACE则是非侵入性设计的典范。
你现在的设计,要求用户差不多同时要掌握function、lambda、tuple。
如果不是因为要使用你这个设计,会有多少情况需要同时使用这么多比较高阶的东西。
而且,按你现在的设计,即使functor不需要参数,也得给个哑参。
[解决办法]
作为一个通用库的实现者,你不能假设用户需不需要支持异质functor,所以,functor的类型应该由用户作为模板参数传入,就如同我前面的代码,用户自己typedef任何东西为PROCESSOR。
相应地,你的add_observer接口应该把function去掉。
[解决办法]
boost::function 去不去各有各的好处
不去,可以把实现写在cpp里面

//hpp
void foo(boost::function x);
//cpp
void foo(boost::function x){
}

热点排行