Reputation: 13
I want to use an unordered_set having as key an unsigned long long*, but I want to implement the hash and the equal_to using the values stored. For instance:
int size = 4;
typedef unsigned long long verylong;
verylong* x = new verylong[size];
// calc hash and equal using x[0]..x[3]
The easy method is to use a wrapper.
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)
//...
}
};
But I don't want to use a wrapper due to memory consumption. I want something like:
std::unordered_set<verylong*,MyHash,MyEqual> set;
The problem is to implement MyHash and MyEqual, because the arraySize is not constant (I only know arraySize in execution time).
I tried this:
typedef struct MyHash
{
int arraySize;
MyHash(int size) : arraySize(arraySize) {}
long operator() (const verylong* const k) const { return hash(k,size); }
} MyHash;
But I cannot use this, because MyHash is not constexpr.
Is what I want possible to do?
EDIT: If I try using the MyHash implemented above:
int size;
// someone sets size a positive value
std::unordered_set<verylong*,MyHash(size),MyEqual> set;
The following error occurs:
error: temporary of non-literal type 'MyHash' in a constant expression std::unordered_set< verylong*, MyHash(size), MyEquals> set;
Upvotes: 1
Views: 1935
Reputation: 62975
The second template argument to std::unordered_set<>
should be MyHash
rather than MyHash(size)
, as a type is expected here rather than an object. Change your set
declaration to:
std::unordered_set<verylong*, MyHash, MyEqual> set(bucket_count, MyHash(size));
Presumably MyEqual
will need a similar argument for size
, in which case do:
std::unordered_set<verylong*, MyHash, MyEqual> set(bucket_count, MyHash(size), MyEqual(size));
For bucket_count
, use a guesstimate of how many elements will be in your set.
As a side note, don't typedef
your struct
s that way – that's a hideous C-ism that serves no purpose in C++.
Upvotes: 3