With C++20's heterogeneous lookups this can be done (see documentation of unordered_map::find()
). For this to work a hash functor and a equality functor have to be defined, e.g.:
struct hash {
template <typename T>
auto operator()(const std::pair<T, T>& pair) const {
return std::hash<T>{}(pair.first) ^ std::hash<T>{}(pair.second); // not to be used in production (combining hashes using XOR is bad practice)
}
using is_transparent = void; // required to make find() work with different type than key_type
};
struct equal {
template <typename A, typename B>
auto operator()(const std::pair<A, A>& a,
const std::pair<B, B>& b) const {
return a.first == b.first && a.second == b.second;
}
using is_transparent = void; // required to make find() work with different type than key_type
};
The type of the map then has to be changed to std::unordered_map<std::pair<std::string, std::string>, int, hash, equal>
in order to use the defined functors.
find()
now works as intended:
using namespace std::literals;
std::unordered_map<std::pair<std::string, std::string>, int, hash, equal> map{};
map.insert({std::pair{"a"s, "b"s}, 42});
if (auto it = map.find(std::pair{"a"sv, "b"sv}); it != map.end())
std::cout << it->second << std::endl;
if (auto it = map.find(std::pair{"x"s, "y"s}); it != map.end())
std::cout << it->second << std::endl;
// prints 42
The implementation can be played with here