In my code I'd like to make unordered sets with only one template parameter (if possible) like so:
std::unordered_set<std::shared_ptr<Foo>> my_foos;
The problem is that my Foo class also have a class member which is of the type std::unordered_set<std::shared_ptr<Foo>>. Specifically my Foo class looks something like this:
#include<unordered_set>
#include<memory>
class Foo {
explicit Foo(int val) : val_(val) {}
void AddFoo(Foo& foo){foos.insert(std::make_shared<Foo>(foo));}
std::unordered_set<std::shared_ptr<Foo>> foos;
int val_;
};
namespace std {
template <>
struct hash<shared_ptr<Foo>> {
size_t operator()(const Foo shared_ptr<Foo>& foo) const {
return hash<int>()(foo->val_);
}
};
template <>
struct equal_to<Foo> {
bool operator()(const Foo shared_ptr<Foo>& lhs, const Foo shared_ptr<Foo>& rhs) const {
return lhs->val_ == rhs->val_;
}
};
}
This gives the error
error: specialization of 'std::hash<std::shared_ptr<Foo> >' after instantiation
How can I resolve this issue?
I got your code to compile. Had to add forward declarations, separate definition from declaration (otherwise it couldn't find
Foo's members) for those structs, addedpublicaccess specifier inFoo. Also, there was some code to cleanup in the function signatures.