Templates 通过枚举值为静态polimorphism选择模板专门化

Templates 通过枚举值为静态polimorphism选择模板专门化,templates,c++03,crtp,Templates,C++03,Crtp,以下是问题的简化示例,以CRTP为特征: #include <type_traits> #include <iostream> enum ActionTypes { eInit = 2 << 0, eUpdate = 2 << 1, eMultUpdate = 2 << 2 }; template <class Data, unsigned Actions =

以下是问题的简化示例,以CRTP为特征:

#include <type_traits>
#include <iostream>

enum  ActionTypes {
    eInit      = 2 << 0,
    eUpdate    = 2 << 1,
    eMultUpdate = 2 << 2
};

template <class Data, 
          unsigned  Actions = eInit|eUpdate|eMultUpdate>
class ActionData
{
    template<ActionTypes As /*???*/>
    struct action {
        static void exec(Data*) { std::cout << "ActionData:: /*dummy*/ exec()\n"; };
        static void exec(Data*,int) { std::cout << "ActionData::/*dummy*/ exec(int)\n"; };
    };

    template<>
    struct action < /*???*/ > 
    {
        static void exec(Data*) { /*...*/ };
    };

    template<>
    struct action < /*???*/ >
    {
        static void exec(Data*, int) {  /*...*/  };
    };

    Data* derived() { return static_cast<Data*>(this); }
protected:
    void init()          { action<eInit>::exec(derived()); }
    void update()        { action<eUpdate>::exec(derived()); }
    void update(int key) { action<eMultUpdate>::exec(derived()); }
public:
    enum Keys { DEFAULT_KEY = -1 };

    void call(ActionTypes a, int key = DEFAULT_KEY)
    {
        switch (a) {
        case eInit:
            init(); break;
        case eUpdate:
            if (key == DEFAULT_KEY)
                update();
            else
        case eMultUpdate:
                update(key);
        }
    }

};

class Test : public ActionData<Test, eUpdate>
{
public:
    void update() { std::cout << "Test :: update()\n";  }
};


int main()
{
    Test actor;
    ActionTypes a = eInit;
    actor.call(a, 0); // useless here but must be possible.
    actor.call(eUpdate, 0);
    actor.call(eUpdate);
}
#包括
#包括
枚举操作类型{

eInit=2我没有意识到我应该对所有情况使用部分专门化,包括不匹配的情况:

#include <type_traits>
#include <iostream>

enum  ActionTypes {
    eInit      = 2 << 0,
    eUpdate    = 2 << 1,
    eMultUpdate = 2 << 2
};

template <class Data, 
          unsigned  Actions = eInit|eUpdate|eMultUpdate>
class ActionData
{
    // Never gets selected
    template<ActionTypes A, typename Enable = void > struct action {};

    template< ActionTypes A >
    struct action<A, typename std::enable_if<(A & Actions) == 0>::type >
    {
        static void exec(Data*) { std::cout << "ActionData:: /*dummy*/ exec()\n"; };
        static void exec(Data*,int) { std::cout << "ActionData::/*dummy*/ exec(int)\n"; };
    };

    template< ActionTypes A >
    struct action < A, typename std::enable_if<(A & Actions) == eInit>::type  >
    {
        static void exec(Data* o) { o->Data::init(); };
    };

    template< ActionTypes A >
    struct action < A, typename std::enable_if<(A & Actions) == eUpdate>::type  >
    {
        static void exec(Data* o) { o->Data::update(); };
    };

    template< ActionTypes A >
    struct action  <  A, typename std::enable_if<(A & Actions) == eMultUpdate>::type >
    {
        static void exec(Data* o, int key) { o->Data::update(key); };
    };

    Data* derived() { return static_cast<Data*>(this); }
protected:
    void init()          { action<eInit>::exec(derived()); }
    void update()        { action<eUpdate>::exec(derived()); }
    void update(int key) { action<eMultUpdate>::exec(derived(), key); }
public:
    enum Keys { DEFAULT_KEY };

    void call(ActionTypes a, int key = DEFAULT_KEY)
    {
        switch (a) {
        case eInit:
            init(); break;
        case eUpdate:
            if (key == DEFAULT_KEY) {
                update();
                break;
            } else {
        case eMultUpdate:
                update(key);
                break;
            };
        }
    }

};

class Test : public ActionData<Test, eUpdate>
{
public:
    void update() { std::cout << "Test :: update()\n";  }
};


int main()
{
    Test actor;
    ActionTypes a = eInit;

    actor.call(a, 0);
    actor.call(eUpdate);
    actor.call(eMultUpdate, 0);
}
#包括
#包括
枚举操作类型{
eInit=2
结构操作
{
静态void exec(Data*o){o->Data::update();};
};
模板
结构操作
{
静态void exec(Data*o,int-key){o->Data::update(key);};
};
Data*derived(){return static_cast(this);}
受保护的:
void init(){action::exec(派生());}
void update(){action::exec(派生());}
无效更新(int键){action::exec(派生(),键);}
公众:
枚举键{DEFAULT_KEY};
无效调用(ActionTypes a,int key=DEFAULT_key)
{
开关(a){
案例eInit:
init();中断;
案例更新:
如果(键==默认键){
更新();
打破
}否则{
案例更新:
更新(关键);
打破
};
}
}
};
类测试:公共ActionData
{
公众:
void update(){std::cout