Use enum to determine type of return result ( a hack using Macro )

三世轮回 提交于 2019-12-25 14:01:42

问题


I have many types of game-object that are related together is some ways.
All relations is implemented by Map<K1,K2>.

#include <vector>
using namespace std;

template<class K1,class K2> class Map{ //N:N relation
     public: std::vector<K2*> getK2(K1* k1){/* some code */return std::vector<K2*>();} 
     public: std::vector<K1*> getK1(K2* k2){/* some code */return std::vector<K1*>();}
     //... various function ...
};

Here is the hub class GameRelation that facilitates all relation query :-
(just an example, no need to pay attention to all detail)

class Human{};   class House{};    class Dog{};
class GameRelation{
    public:
    #define RELATION(A,B,EnumName) Map<A,B> Map##EnumName;  \
    enum EnumName##Enum{EnumName};   \
    std::vector<B*> getAllRight(EnumName##Enum e,A* a){  \
        return Map##EnumName.getK2(a);  \
    }
    //... various function ...
    RELATION(Human,House,Own) 
    //I can insert any relation that I want
};

The above macro expands into something like :-

Map<Human,House> MapOwn; 
enum OwnEnum{Own};   
std::vector<House*> getAllRight(OwnEnum e,Human* a){  
    return MapOwn.getK2(a);  
}

Here is how it can be used (full demo):-

int main() {
    GameRelation gameRelation;
    std::vector<House*> houses=gameRelation.getAllRight(GameRelation::Own,new Human()); 
    //get all "House" that is "Own" by a "Human" 
    return 0;
}

After some testing, it works good. Everyone is happy with the magical result.

However, my conscious tell me that it is a hack.
It is also a little bad for content-assist (e.g. intellisense) and automatic refactoring.
I also need the awesome hacking X-MACRO if I want to move their implementation to .cpp.

Question:

  • Is there any elegant (less hack) way? What is it?
    "No" can be a valid answer.
  • Is X-MACRO the (professional) way to go when I need such (strange) feature?

回答1:


struct GameRelation{
    template <typename A, typename B>
    struct Relation {
        std::vector<B*> getAllRight(A* a) {
            return map.getK2(a);
        }

    private:
        Map<A, B> map;
    };

    Relation<Human, House> own;
};

int main() {
    GameRelation gameRelation;
    std::vector<House*> houses = gameRelation.own.getAllRight(new Human()); 
}


来源:https://stackoverflow.com/questions/43556687/use-enum-to-determine-type-of-return-result-a-hack-using-macro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!