Here's one way. Note that I have made the comparator copy/moveable with the use of an observer pointer rather than a reference:
#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;
}
by request, refactored:
#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;
}