std::set компаратор, который ссылается на внешнее значение
У меня есть что-то вроде
class ClassB {
// ....
private:
static std::unordered_map<ClassA,double> activity;
struct compare_values {
bool operator()(const ClassA& l, const ClassA& r) const {
return activity[l] < activity[r];
}
};
std::set<ClassA,compare_values> ordered;
// ...
}
Поскольку мне нужно, чтобы ClassB возвращал объект ClassA с максимальной активностью (только из упорядоченного объекта), удалите некоторый объект ClassA из упорядоченного набора и вставьте новый внутри.
Как я могу удалить статическое требование для unoredered_map? Я хочу, чтобы у каждого объекта ClassB были Compare_values, которые ссылаются на хэш-карту конкретной активности, но я понятия не имею, как передать им карту.
1 ответ
Решение
Вот один из способов. Обратите внимание, что я сделал копию компаратора / перемещаемую с использованием указателя наблюдателя, а не ссылки:
#include <unordered_map>
#include <set>
#include <memory>
struct ClassA {};
std::size_t hash_value(ClassA const&);
bool operator==(ClassA const&, ClassA const&);
namespace std {
template<>
struct hash<::ClassA> {
template<class Arg>
auto operator()(Arg&& arg) const {
return hash_value(arg);
}
};
}
class ClassB {
private:
using activity_map = std::unordered_map<ClassA,double>;
struct compare_values
{
compare_values(activity_map const& activity)
: activity_observer_(std::addressof(activity))
{}
bool operator()(const ClassA& l, const ClassA& r) const {
return activity().at(l) < activity().at(r);
}
private:
auto activity() const -> activity_map const&
{
return *activity_observer_;
}
activity_map const* activity_observer_;
};
activity_map activity {};
std::set<ClassA,compare_values> ordered { compare_values { activity } };
// ...
};
int main()
{
ClassB b;
}
по запросу, рефакторинг:
#include <unordered_map>
#include <set>
#include <memory>
struct ClassA {};
std::size_t hash_value(ClassA const&);
bool operator==(ClassA const&, ClassA const&);
namespace std {
template<>
struct hash<::ClassA> {
template<class Arg>
auto operator()(Arg&& arg) const {
return hash_value(arg);
}
};
}
using ClassA_activity_map = std::unordered_map<ClassA, double>;
struct by_ascending_classA_activity
{
by_ascending_classA_activity(ClassA_activity_map const& activity)
: activity_observer_(std::addressof(activity))
{}
bool operator()(const ClassA& l, const ClassA& r) const {
return activity().at(l) < activity().at(r);
}
private:
auto activity() const -> ClassA_activity_map const&
{
return *activity_observer_;
}
ClassA_activity_map const* activity_observer_;
};
class ClassB {
private:
ClassA_activity_map activity {};
std::set<ClassA, by_ascending_classA_activity> ordered { { activity } };
// ...
};
int main()
{
ClassB b;
}