In the following program the compiler seems to be missing the operator== for the keys in the unordered map. The way I understand it is that std::variant
automatically delegates ==
to it's fields (if the same index is set and false
otherwise). Furthermore, I have a definition of operator==
in the types A
and B
.
#include <variant>
#include <string>
#include <unordered_map>
struct Base {
public:
virtual std::size_t get_hash() const = 0;
};
struct A : public Base {
std::string s;
public:
A(std::string str): s{str} {}
std::size_t get_hash() const override {
return std::hash<std::string>{}(this->s);
}
bool operator==(const A a) {
return a.s == this->s;
}
};
struct B : public Base {
int i;
public:
B(int it): i{it} {}
std::size_t get_hash() const override {
return std::hash<int>{}(this->i);
}
bool operator==(const B b) {
return b.i == this->i;
}
};
namespace std {
template<>
struct hash<A> {
size_t operator()(const A& a) const {
return a.get_hash();
}
};
template<>
struct hash<B> {
size_t operator()(const B& b) const {
return b.get_hash();
}
};
}
int main(int argc, char* argv[])
{
std::unordered_map<std::variant<A,B>, int> map;
std::variant<A,B> key1{A("hi")};
std::variant<A,B> key2{B(1)};
map.insert({key1, 1});
map.insert({key2, 2});
}
Hence, I do not understand why the compiler complains about a lack of equality operator.
CodePudding user response:
The operator==
need to be const
,
also it's better to take a const T&
instead of const T
struct A{
// ...
bool operator==(const A& a) const {
return a.s == this->s;
}
};
struct B{
// ...
bool operator==(const B& b) const {
return b.i == this->i;
}
};