My main data object is a array of doubles of a length that depends on a specific instantiation of my class. I would like to construct a very simple hash table to store/retrieve these objects, and we can assume that the numbers are generated in a way that is free of numerical error.
int main() {
std::tr1::unordered_map<double*, double*> cache;
double x1[] = { 1.0, 3.14 };
double x2[] = { 1.0, 3.14 };
cache[x1] = x1;
std::cout << "x1: " << cache.count(x1) << std::endl;
std::cout << "x2: " << cache.count(x2) << std::endl;
return 0;
}
The above obviously only compares the pointers, giving the output:
> ./tmp
x1: 1
x2: 0
When I really want to see:
> ./tmp
x1: 1
x2: 1
It's pretty clear how to create custom hashing and equality functions when the size of the arrays are fixed at compile time but I do not know how to make custom functions that depend on a specific instantiation... I created a class below, but I'm not sure if it's useful, or how it could be used.
class Hash_double_vec {
public:
int dim;
Hash_double_vec(int d) { dim = d; }
size_t operator()(const double *x) const{
std::tr1::hash<double> hash_fn;
size_t r = hash_fn(x[0]);
for(int i=1;i<dim;i++) r ^= hash_fn(x[i]);
return r;
}
bool operator()(const double *x, const double *y) const{
for(int i=1;i<dim;i++) if (fabs(x[i]-y[i]) > 1e-10) return false;
return true;
}
};
One way would be to create struct to hold the pointer to the sequence of doubles:
And then use it:
Of course it is your problem to make sure the lifetime of the backing memory is a superset of the lifetime of the DoubleRegion.
Old Answer:
If you don't know until runtime how big the key and value is going to be, use a std::vector:
If you know at compile-time how big you can use an std::array:
In both cases the default hashing function will work by value as you want, and you do not need to define a custom one.