I have created a hasher class for a custom type I'm using, but it has a constructor that takes an argument. I can't figure out the syntax to use this in an unordered_set.
class Hasher {
unsigned arg;
public:
Hasher(unsigned a) : arg(a) {}
size_t operator()(const MyType& t) const {
return calculate_hash(arg, t);
}
}
int main() {
unordered_set<MyType, Hasher(2)> myset; // compilation error
}
The error message:
In file included from Tetrahedron.cc:5:
./Triangulation.h:52:29: error: template argument for template type parameter must be a type
unordered_set<TetraFace,FaceHasher(2)> faces2;
^~~~~~~~~~~~~
/bin/../lib/gcc/x86_64-redhat-linux/6.3.1/../../../../include/c++/6.3.1/bits/unordered_set.h:90:11: note: template parameter is declared here
class _Hash = hash<_Value>,
^
I also tried
unordered_set<MyType, Hasher> myset(Hasher(2));
but I still get an error:
In file included from Tetrahedron.cc:5:
./Triangulation.h:52:59: error: expected ')'
unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2));
^
./Triangulation.h:52:58: note: to match this '('
unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2));
^
You're getting a compile error there because you're trying to pass an object (i.e. instance) of type Hasher as a template argument.
Like your error describes: template argument for template type parameter must be a type
It's expecting a type, and you're passing in a value.
Parameterize the arg at the type level.
template<unsigned A>
class Hasher {
unsigned arg = A;
public:
size_t operator()(const int& t) const {
std::cout << arg << std::endl;
return 0;
}
};
int main() {
std::unordered_set<int, Hasher<2>> myset;
myset.insert(5); // prints 2
std::unordered_set<int, Hasher<3>> myset2;
myset2.insert(3); // prints 3
}