在unordered_set中使用数组作为键

时间:2014-08-08 21:15:10

标签: c++ arrays c++11 hash unordered-set

我想使用 unordered_set 作为 unsigned long long * 的关键字,但我想实现哈希 equal_to 使用存储的值。例如:

int size = 4;
typedef unsigned long long verylong;
verylong* x = new verylong[size];
// calc hash and equal using x[0]..x[3]

简单的方法是使用包装器。

class VeryLong {
verylong* array;
int arraySize;
...
bool operator==(const VeryLong& x) { // use the array and arraySize }
...
};
namespace std {

template <>
class hash<VeryLong>
{
    std::size_t operator()(const VeryLong& v) const
    {

     // Compute hash values for array (using murmur, maybe)
     //...
    }
};

但由于内存消耗,我不想使用包装器。我想要这样的东西:

std::unordered_set<verylong*,MyHash,MyEqual> set;

问题是实现 MyHash MyEqual ,因为arraySize不是常量(我只知道执行时间的arraySize)。

我试过了:

typedef struct MyHash
{
    int arraySize;
    MyHash(int size) : arraySize(arraySize) {}
    long operator() (const verylong* const k) const { return hash(k,size); }
} MyHash;

但我无法使用此功能,因为 MyHash 不是 constexpr

我想要做什么?

编辑:如果我尝试使用上面实现的MyHash:

int size;
// someone sets size a positive value 
std::unordered_set<verylong*,MyHash(size),MyEqual> set;

发生以下错误:

错误:在常量表达式std :: unordered_set&lt;中的非文字类型'MyHash'的临时性非常长*,MyHash(大小),MyEquals&gt;设置;

1 个答案:

答案 0 :(得分:3)

std::unordered_set<>的第二个模板参数应该是MyHash而不是MyHash(size),因为此处需要类型而不是对象。将您的set声明更改为:

std::unordered_set<verylong*, MyHash, MyEqual> set(bucket_count, MyHash(size));

大概MyEqual需要size的类似论据,在这种情况下:

std::unordered_set<verylong*, MyHash, MyEqual> set(bucket_count, MyHash(size), MyEqual(size));

对于bucket_count,请使用您对集合中元素数量的估计。

作为旁注,不要typedef struct这样做 - 这是一个在C ++中没有用处的可怕的C主义。