I'm trying to write a genreric Hash function to be consumed in a hash table I'm going to use in the program runtime.
But I'm stuck here with a problem, to use the constexpr std::hash() function. I want to dynamically enumerate my tuple values, but I am not being able to do that by specifing constexpr in my operator overload method.
What am I doing wrong?
#include <iostream>
#include <unordered_map>
using llong = long long;
using ullong = unsigned long long;
using tlong = std::tuple<llong, llong>;
using tllong = std::tuple<llong, llong, llong>;
using tlllong = std::tuple<llong, llong, llong, llong>;
using tulong = std::tuple<ullong, ullong>;
using tullong = std::tuple<ullong, ullong, ullong>;
using tulllong = std::tuple<ullong, ullong, ullong, ullong>;
template<class Args>
struct KeyHash
{
constexpr std::size_t operator()(const Args &args) const
{
std::size_t seed = 1, _size = std::tuple_size<Args>::value;
for(auto i = 0ul; i< _size; i++)
{
seed += std::hash<std::tuple_element<(const std::size_t)i, Args>::type>()(std::get<i>(args)) + 0x2e3dbcd34 + (seed << 6) + (seed >> 4);
}
return seed;
}
};
template<class Args>
struct KeyEqual
{
bool operator()(const Args &v1, const Args &v2) const
{
return (v1 == v2);
}
};
using umtlong = std::unordered_map<tlong, int, KeyHash<tlong>, KeyEqual<tlong>>;
using umtllong = std::unordered_map<tllong, int, KeyHash<tllong>, KeyEqual<tllong>>;
using umtlllong = std::unordered_map<tlllong, int, KeyHash<tlllong>, KeyEqual<tlllong>>;
using umtulong = std::unordered_map<tulong, int, KeyHash<tlong>, KeyEqual<tlong>>;
using umtullong = std::unordered_map<tullong, int, KeyHash<tllong>, KeyEqual<tllong>>;
using umtulllong = std::unordered_map<tulllong, int, KeyHash<tlllong>, KeyEqual<tlllong>>;
int main()
{
return 0;
}
The error, I'm getting here is
g++ hash-map-tuple-keys.cc -o hash-map-tuple-keys.o -std=c++17
hash-map-tuple-keys.cc:21:50: error: non-type template argument is not a constant expression
seed += std::hash<std::tuple_element<(const std::size_t)i, Args>::type>()(std::get<i>(args)) + 0x2e3dbcd34 + (seed << 6) + (seed >> 4);
^~~~~~~~~~~~~~~~~~~~
hash-map-tuple-keys.cc:21:69: note: read of non-const variable 'i' is not allowed in a constant expression
seed += std::hash<std::tuple_element<(const std::size_t)i, Args>::type>()(std::get<i>(args)) + 0x2e3dbcd34 + (seed << 6) + (seed >> 4);
^
hash-map-tuple-keys.cc:19:18: note: declared here
for(auto i = 0ul; i< _size; i++)
^
1 error generated.