search

Home  >  Q&A  >  body text

C/C++中写一个函数,如何代替if else,switch,while等语句来实现 "不同值 对应调用 不同函数"?

功能类似如下描述:
if n==23 , 调用void fun1(void);
if n==33 , 调用void fun2(void );
if n==57 , 调用void fun3(void );
if n==246 , 调用void fun4(void );
if n==132 , 调用void fun5(void );

待实现如下函数:(5个fun函数已知,n 一定为{23,33,57,246,132}中的一个)

void Test(int n)
{
    ...
}

我想到了map<int,pFun>应该可以解决,大家还有其他方法吗?

怪我咯怪我咯2787 days ago1164

reply all(9)I'll reply

  • 迷茫

    迷茫2017-04-17 13:14:01

    Reminds me of a routine I wrote many years ago. The idea is similar to yours, except that map is not used (in fact, when the amount of data is small, the performance of not using map is better):

    #include <stdio.h>
    #include <string.h>
    
    typedef void(*VOID_FUNC_PTR)(void);
    
    typedef struct
    {
        char *pszInput;
        VOID_FUNC_PTR func;
    } FUNC_REG;
    
    void hello(void)
    {
        puts("I know you are saying hello.");
    }
    
    void hey(void)
    {
        puts("hey~hey.");
    }
    
    void someother(void)
    {
        puts("some more out put.");
    }
    
    void defaultFunc(void)
    {
        puts("there is no function for this anyway.");
    }
    
    FUNC_REG func_reg_list[] = 
    {
        "hello", hello,
        "hey", hey,
        "someother", someother
    };
    
    VOID_FUNC_PTR LookupFunc(char *pszInput)
    {
        int i;
        for (i = 0; i < sizeof(func_reg_list) / sizeof(func_reg_list[0]); i++)
        {
            if (0 == strcmp(pszInput, func_reg_list[i].pszInput))
            {
                return func_reg_list[i].func;
            }
        }
        return defaultFunc;
    }
    
    int main()
    {
        VOID_FUNC_PTR func = NULL;
        char szInput[256];
        
        while (EOF != scanf("%s", szInput))
        {
            func = LookupFunc(szInput);
            if (func != NULL)
            {
                (*func)(); 
            }
        }
        return 0;
    } 
    

    Original text: http://blog.csdn.net/cashey1991/article/details/8333954

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 13:14:01

    If you want to complete a Turing-complete structure, you should use the chain of responsibility pattern:

    class IAction
    {
    public:
        ~IAction(){}
        virtual void DoSomething(int value) = 0;
    };
    
    struct ActionFilterResult
    {
        bool runTheAction;
        bool continueFiltering;
        IAction* action;
    };
    
    class IActionFilter
    {
    public:
        ~IActionFilter(){}
        virtual ActionFilterResult Evaluate(int value) = 0;
    };
    
    vector<unique_ptr<IActionFilter>> filters;
    
    void Run(int value)
    {
        for(auto& filter : filters)
        {
            auto result = filter->Evaluate(value);
            if (result.runTheAction) result.action->DoSomething(value);
            if (!result.continueFiltering) break;
        }
    }

    reply
    0
  • PHPz

    PHPz2017-04-17 13:14:01

    I’ll just talk about a copycat algorithm, never use if, else, while.... Haha
    (n == 23 && func1())
    || (n == 33 && fun2() )
    || (n == 57 && fun3())
    || (n == 246 && fun4())
    || (n == 132 && func5());

    Use the short-circuit evaluation characteristics of && and || to implement if,else

    reply
    0
  • 阿神

    阿神2017-04-17 13:14:01

    typedef void (*pfunc)(void);
    pfunc arrfunc[16];
    arrfunc[1]=func1;
    arrfunc[2]=func2;
    arrfunc[3]=func3;
    arrfunc[8]=func5;
    arrfunc[15]=func4;
    (arrfunc[n/16])();

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:14:01

    The first thing I thought of was goto...

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:14:01

    For c++11, you can use function instead of function pointer;

    #include <iostream>
    #include <functional>
    #include <map>
    using namespace std;
    
    void fun1()
    {
        cout << "fun1\n";
    }
    void fun2()
    {
        cout << "fun2\n";
    }
    void fun3()
    {
        cout << "fun3\n";
    }
    int main()
    {
        map<int, function<void()>> funs;
        funs[23] = fun1;
        funs[33] = fun2;
        funs[57] = fun3;
    
        funs[23]();
        
        
        return 0;
    }
    

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:14:01

    void f0() { cout << "this is function 0"; }
    void f1() { cout << "this is function 1"; }
    void f2() { cout << "this is function 2"; }
    void f3() { cout << "this is function 3"; }
    void f_default() { cout << "out of range"; }
    
    
    std::map<int, void(*)(void)> f = {
      { 12, f0 },
      { 32, f1 },
      { 48, f2 },
      { 99, f3 },
    };
    
    (f.count(n) ? f[n] : f_default)();
    

    reply
    0
  • 黄舟

    黄舟2017-04-17 13:14:01

    result = a==1?func():a==2?func2():a==3?func3():func4();

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 13:14:01

    Can’t help anyone, deleted

    reply
    0
  • Cancelreply