使用类成员变量来保存内部结构定义中的函数,这些函数将用作unordered_map对象的模板参数

时间:2015-10-18 06:20:54

标签: c++ class struct key unordered-map

我正在实现一个使用unordered_map的对象。该对象是通用的,因此模板无处不在。特别是operator==operator()被包装到unordered_map使用的结构中,以分别检查密钥是否相等并生成密钥的哈希值。我希望用户编写自己的函数来实现上述两个运算符,并将这些方法作为输入传递给类对象。然后结构将使用这些对象。我在使用示波器方面遇到了一些麻烦,似乎无法弄清楚如何做到这一点。这是我的代码:

#include <unordered_map>
#include <iostream>
#include <string>
#include <functional>

template <typename O>
class aClass
{
public:
    aClass( bool        (usrIsEq)(O, O) , 
            std::size_t (usrHashFtn)(O) ) 
    {
        this->usrIsEq    = usrIsEq;
        this->usrHashFtn = usrHashFtn;
    }

    void add(O k, std::string v)
    {
        iTable[ {k} ] = v;
    }

    std::string get(O k)
    {
        return iTable[ {k} ];
    }


private:
    bool        (*usrIsEq)(O, O);
    std::size_t (*usrHashFtn)(O);

    struct Key
    {
        O obj;

        bool operator==(const Key &other)    const
        {
            std::cout <<  "obj " <<   obj << std::endl;
            return usrIsEq(obj, other.obj);
        }
    };

    struct KeyHasher
    {
        std::size_t operator()(const Key &k) const
        {
            return usrHashFtn(k);
        }
    };  
    std::unordered_map<Key, std::string, KeyHasher> iTable;

};

bool isEqInts(int a, int b)
{
    return a == b;
}

std::size_t intHashFtn(int x)
{
    std::hash<int> hf;
    return  hf(x);
}

int main()
{
    aClass<int> x(isEqInts, intHashFtn);
    x.add( 1, std::string("hello") );
}

我不完全确定如何实施struct s KeyKeyHasher,以便他们使用类中包含的函数。我唯一真正关心的是函数作为类构造函数的输入。其他一切都可以废弃。

1 个答案:

答案 0 :(得分:0)

绊倒你的主要问题是Key没有usrIsEq知识,而KeyHasher不知道usrHashFtn。您需要将aClass对象的指针或引用传递给这些类。

这里有一个建议:

struct Key
{
    O obj;
    aClass* ac;

    bool operator==(const Key &other)    const
    {
        std::cout <<  "obj " <<   obj << std::endl;
        return ac->usrIsEq(obj, other.obj);
    }
};

struct KeyHasher
{
    std::size_t operator()(const Key &k) const
    {
        return k.ac->usrHashFtn(k.obj);
    }
};  

并更新您使用Key访问该表的位置:

void add(O k, std::string v)
{
    iTable[{k, this}] = v;
}

std::string get(O k)
{
    return iTable[{k, this}];
}