Reputation: 35
Here, I tried to make a map that its vertex can be user-defined class. But when I try to add template type element to the unordered_set it gives error. The code is:
#include <iostream>
#include <unordered_set>
#include <string>
#include <vector>
#include <functional>
template<class T> class Edge;
template<class T> class Vertex{ // Made it a class just for its constructor.
public:
template<class A> Vertex(A vert){
A vertex = vert;
std::unordered_set<Edge<A>> adjlist;
}
};
template<class T> class Edge{ // Made it a class just for its constructor.
public:
template<class A> Edge(Vertex<A> vert1, Vertex<A> vert2, int w){
Vertex<A> *origin = &vert1;
Vertex<A> *target = &vert2;
}
};
template<class T>
class WUG{
private:
std::unordered_set<Vertex<T>> vertices;
std::unordered_set<Edge<T>> edges;
int num_of_edges;
int num_of_vertices;
public:
WUG() {
num_of_edges = 0;
num_of_vertices = 0;
}
void addVertex(T newVert) {
Vertex<T> temp = Vertex<T>(newVert);
vertices.emplace(temp); //Problem is here
}
int main(int argc, char** argv) {
WUG<char> g1 = WUG<char>();
g1.addVertex('A');
g1.addVertex('B');
g1.addVertex('C');
return 0;
}
Error: it opens hashtable_policy.h and gives error at
template <typename _Key, typename _Hash>
struct __is_noexcept_hash : std::integral_constant<bool,
noexcept(declval<const _Hash&>()(declval<const _Key&>()))> //Here
{ };
[Error] no match for call to '(const std::hash<Vertex<char> >) (const Vertex<char>&)'
How do you emplace a template type object to unordered_set? How about pair of 2 template?
Upvotes: 1
Views: 1378
Reputation: 51
I believe you need to provide special hashing and comparison functions to make the hash set (or in my example's case, hash map) work. Here is a minimal example. Tested with C++11.
#include <unordered_map>
#include <iostream>
#include <algorithm>
template<typename T>
struct foo {
typedef T value_type;
foo(T x) : x(x) {}
T x;
};
template<typename T>
struct foo_hasher {
int operator()(const T &val) const {
return std::hash<typename T::value_type>()(val.x);
}
};
template<typename T>
struct foo_equality {
bool operator()(const T &left, const T& right) const {
return left.x == right.x;
}
};
int main() {
typedef std::unordered_map<foo<int>, int, foo_hasher<foo<int>>, foo_equality<foo<int>>> Map;
Map mp;
foo<int> x(5);
mp[x] = 10;
mp[foo<int>(10)] = 22;
std::for_each(mp.begin(), mp.end(), [](const Map::value_type &val) {
std::cout << val.first.x << ", " << val.second << "\n";
});
}
Note that both my hashing and equality function are not at all restrictive - they are wrt T rather than foo, but the principal should be the same.
Upvotes: 2