std::set 引用外部值的比较器
std::set Comparator that refer to external value
我有类似的东西
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 到 return 最大 activity 的 ClassA 对象(仅来自有序的对象),从有序集中删除一些 ClassA 对象并在其中插入新对象。
如何删除 unoredered_map 的静态要求?我希望每个 ClassB 对象都有一个 compare_values 引用特定的 activity 哈希映射,但我不知道如何将映射传递给它们。
这是一种方法。请注意,我使用观察者指针而不是引用制作了比较器 copy/moveable:
#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;
}
我有类似的东西
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 到 return 最大 activity 的 ClassA 对象(仅来自有序的对象),从有序集中删除一些 ClassA 对象并在其中插入新对象。
如何删除 unoredered_map 的静态要求?我希望每个 ClassB 对象都有一个 compare_values 引用特定的 activity 哈希映射,但我不知道如何将映射传递给它们。
这是一种方法。请注意,我使用观察者指针而不是引用制作了比较器 copy/moveable:
#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;
}