Благодаря предложениям Гетерогенного поиска неупорядоченных контейнеров (http://wg21.link/P0919r3 и http://wg21.link/p1690r1) эта проблема решена в C++20. Но имеющееся решение мне кажется довольно неуклюжим (даже по стандартам C++). Похоже, мне нужно реализовать с нуля не один, а два функтора (для прозрачного хеширования и для прозрачного сравнения):
Код: Выделить всё
template
struct Equal {
using is_transparent = void;
bool operator()(const std::unique_ptr& lhs, const std::unique_ptr& rhs) const {
return lhs == rhs;
}
bool operator()(const std::unique_ptr& lhs, const T* rhs) const {
return lhs.get() == rhs;
}
bool operator()(const T* lhs, const std::unique_ptr& rhs) const {
return lhs == rhs.get();
}
};
template
struct Hash {
using is_transparent = void;
size_t operator()(const std::unique_ptr& ptr) const {
return std::hash()(ptr.get());
}
size_t operator()(const T* ptr) const {
return std::hash()(ptr);
}
};
template
using UnorderedSetOfUniquePtrs = std::unordered_set;
Это работает, но выглядит как МНОГО шаблонного кода. Я что-то упускаю? Есть ли способ использовать IDK, возможно, какой-нибудь стандартный прозрачный хэшер или компаратор равенства? Я вижу, что std::equal_to прозрачен, но не могу использовать его напрямую. Может быть, есть хитрый способ определить неявное преобразование unique_ptr -> T* «только для этого класса UnorderedSetOfUniquePtrs»? Ваши идеи приветствуются.
Подробнее здесь: https://stackoverflow.com/questions/642 ... ue-ptr-c20
Мобильная версия