Reputation: 365
I'm having a hard time calling hash_value.
From this post, I want to apply to vector<vector<E>>
where E is a custom object.
My codes as follows:
struct E;
class myclass {
private:
vector<E> lhs;
public:
myclass(const vector<E>& v) :lhs{ v } { };
static size_t hash_value(const vector<E>& v) {
size_t seed = 0;
boost::hash_combine(seed, d.name);
boost::hash_combine(seed, d.scope);
return seed;
}
bool operator==(const vector<E> >& rhs) {
for (unsigned i = 0; i < lhs.size(); i++)
if (lhs[i].name != rhs[i].name || lhs[i].scope!= rhs[i].scope)
return false;
return true;
};
};
then i call this code:
void test(std::vector<std::vector<E>>& A)
{
boost::unordered_set < myclass > input_records(A.size());
for (BOOST_AUTO(it, A.begin()); it != (A.end());) {
auto k = input_records.insert(myclass{*it}); <<--
....
}
}
however i get an error:
Also, in some cases this code executes but hash_value is never called. I'm not sure what am I missing?
How do I fix this?
Upvotes: 0
Views: 320
Reputation: 595887
You are trying to use boost::unordered_set<myclass>
, which will internally use boost::hash<myclass>
, which will look for a hash_value(myclass)
function in the same namespace as myclass
via Argument-Dependent Lookup. You made your hash_value()
be a non-static member of myclass
, so boost::hash
will not be able to find it. But even if it could, it expects your hash_value()
to take a single myclass
object as a parameter, not a vector
.
See Extending boost::hash for a custom data type in Boost's documentation.
Also, a class's operator==
compares *this
to another object. Inside of myclass
, your operator==
should take a single myclass
object as a parameter, not a vector
.
Try this instead:
struct E {
string name;
int scope;
};
size_t hash_value(const E& obj) {
std::size_t seed = 0;
boost::hash_combine(seed, obj.name);
boost::hash_combine(seed, obj.scope);
return seed;
}
class myclass {
private:
vector<E> vec;
public:
myclass(const vector<E>& v) : vec(v) {}
bool operator==(const myclass& rhs) const {
// vector has its own operator== for comparing elements in its array...
return vec == rhs.vec;
}
friend size_t hash_value(const myclass& obj) {
return boost::hash_range(obj.vec.begin(), obj.vec.end());
}
};
void test(std::vector<std::vector<E>>& A)
{
boost::unordered_set<myclass> input_records(A.size());
for (BOOST_AUTO(it, A.begin()); it != (A.end());) {
auto k = input_records.insert(*it);
...
}
}
Upvotes: 2