C++ 使用enum确定返回结果的类型(使用宏的黑客攻击)

C++ 使用enum确定返回结果的类型(使用宏的黑客攻击),c++,enums,macros,c++14,x-macros,C++,Enums,Macros,C++14,X Macros,我有许多类型的游戏对象,它们以某种方式相互关联。 所有关系都通过Map实现 #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*>();} p

我有许多类型的游戏对象,它们以某种方式相互关联。
所有关系都通过
Map
实现

#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 ...
};
上面的宏扩展为如下内容:-

Map<Human,House> MapOwn; 
enum OwnEnum{Own};   
std::vector<House*> getAllRight(OwnEnum e,Human* a){  
    return MapOwn.getK2(a);  
}
MapOwn;
enum Own enum{Own};
向量getAllRight(owneum e,Human*a){
返回MapOwn.getK2(a);
}
下面是如何使用它():-

intmain(){
博弈关系;
std::vector houses=gameRelation.getAllRight(gameRelation::Own,new Human());
//获得所有“人类”拥有的“房子”
返回0;
}
经过一些测试,它运行良好。每个人都为这个神奇的结果感到高兴

然而,我的意识告诉我这是一种黑客行为。
这对内容辅助(例如intellisense)和自动重构也有点不利。
如果我想将它们的实现转移到
.cpp
,我还需要可怕的黑客攻击X-MACRO

问题:

  • 有什么优雅的(不太粗鲁的)方法吗?这是什么?
    “否”可能是一个有效的答案
  • 当我需要这种(奇怪的)功能时,X-MACRO是(专业的)方式吗
结构游戏关系{
模板
结构关系{
std::vector getAllRight(A*A){
返回图。getK2(a);
}
私人:
地图;
};
自身关系;
};
int main(){
博弈关系;
std::vector houses=gameRelation.own.getAllRight(new Human());
}

我发现的唯一(次要)缺点是它的封装程度较低-我将直接访问字段“own”。@javaLover为什么这是一个问题<代码>关系专门用作访问器,不提供它们就可以禁止对其进行任何不需要的操作。这是一句智慧的话。请告诉我这项技术叫什么?。。。创建只包含单一/通用类型字段的类的技术…@javaLover我不知道它有任何通用名称。
使用namespace std?哦,得了吧,你比这更好……看起来你正试图用命令式编程语言用枚举和宏重新创建关系数据模型。您是否考虑过只使用类似SQLite的东西?你可以有一张表“house”,一张表“human”和一张表“house_Ownersh”,上面有前两张表的外键。@Quentin同意,这只是为了演示。这是“ideone”的默认设置。@Christian Hackl是的,我也感觉到了,但我从来都不知道有这样的库。感谢SQLite是否使用哈希函数?我讨厌杂烩,它很慢。(我分析了std::unordered_map。)@javaLover:我不知道SQLite实际上是如何实现的,但当您需要基于本地文件的关系数据库时,它是标准的行业解决方案。例如,Android、iOS、Firefox和最新的VisualStudioIDE都使用它。但是,如果您需要完全存储在内存中的某些内容,并且无法承担I/O操作,那么这可能是错误的选择。
Map<Human,House> MapOwn; 
enum OwnEnum{Own};   
std::vector<House*> getAllRight(OwnEnum e,Human* a){  
    return MapOwn.getK2(a);  
}
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;
}
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()); 
}