映射逻辑上相似的抽象类的键

时间:2016-04-25 08:27:56

标签: c++ dictionary

假设用户使用包含kBase vBase个类的库。用户添加了对他们可用的类的键和值的值(他使用库实现了它们) - vk。在库中,当添加时,我想要逻辑上相似的键(具有相同的字符串)"合并"成一把钥匙。

他是我尝试过的代码示例:

//---------------------------LIBRARY.h------------------------//

#include <map>
#include <vector>
#include <iostream>

using namespace std;   

map<kBase*,vector<vBase*>> mapa;

void printMap();
void addToMap(kBase* k1, vBase* v2);

class kBase {
public:
    virtual ~kBase(){}
};

class vBase {
public:
    virtual ~vBase(){}
};

//---------------------------LIBRARY.cpp------------------------//

void printMap()
{
    // Expect 3 keys to be implemented.
    for (auto i : mapa)
        cout << i.first << endl;
}

void addToMap(kBase* k1, vBase* v2)
{
    // Create a k1. if it doesnt exist - vector will be created.
    // Otherwise, the object will be obtained.
    mapa[k1];
    mapa[k1].push_back(v2);
}

//------------------------USER----------------------------//

#include "LIBRARY.h"

// User's implementation.
class k : public kBase {
public:
    k(string inputString)
    {
        kString = inputString;
    }
    ~k(){}

    string kString;
};

class v : public vBase {
public:

    v(string inputString)
    {
        vString = inputString;
    }
    ~v(){}

    string vString;
};

int main()
{
    // User adds keys and values
    addToMap(new k("key1"), new v("value1"));
    addToMap(new k("key1"), new v("value2"));
    addToMap(new k("key1"), new v("value3"));

    addToMap(new k("key2"), new v("value4"));
    addToMap(new k("key2"), new v("value5"));
    addToMap(new k("key2"), new v("value6"));

    addToMap(new k("key3"), new v("value7"));
    addToMap(new k("key3"), new v("value8"));
    addToMap(new k("key3"), new v("value9"));

    printMap();

    return 0;
}

显然,我不能直接将基类作为键添加。并且库不知道用户实现的类(继承自库的类)。但同样,图书馆如何知道给定的对象在逻辑上是否相似。

我应该为此目的使用不同的数据结构吗?

1 个答案:

答案 0 :(得分:3)

C++ map uses the equivalence concept for finding the entry, which is defined via “less” comparison. Two keys k1 and k2 are considered equivalent if k1 “is not less than” k2 and k2 “is not less than” k1. So all you need is to define the functor for comparing pointers to kBase class.

class kBaseLessCompare
{
public:
    bool operator() (const kBase * k1, const kBase * k2)
    {
        // something like the following, but you shall define your comparison
        return k1->name < k2->name;
    }
}

Then change your map definition to the following:

map<const kBase*, vector<vBase*>, kBaseLessComapre> mapa;