我有一个类,并且指向此类对象的指针需要放在std::set
中。我想在类中定义比较器。我已经看到了一些解决方案,其中定义了一个单独的类(我猜它被称为仿函数),或者定义了一个重载operator()
的结构。我想避免使用这个样板代码,并希望将比较器定义为类本身的成员,这与Java的compareTo()
方法类似。
让我们说,我的班级是这样的:
class Item {
private:
int id;
float score;
.....
public:
// Rest of the methods and setters/getters
}
我想以一种方式定义比较器,使得具有较高分数的对象的指针首先放在该集合中。如果两者的分数相等,则首先放置具有较低id的分数。我想代码会像下面那样,但由于我不太了解这一部分,请纠正我(我希望将它放在类中):
bool operator()(const Item* a, const Item* b) {
if (a->score != b->score) return a->score > b->score;
return a->id < b->id;
}
用法如下:
std::set<Item*> sortedItems;
Item* item = new Item();
sortedItems.insert(item);
我不确定是否需要在std::set
模板中指定比较器(如果在类中定义),如果是,那么如何?另外,如何在类本身中添加此比较器?我是STL的新手,也是C ++的新手。谢谢!
答案 0 :(得分:5)
此解决方案的灵感来自此answer。
#include <set>
class Item {
private:
int id;
float score;
public:
struct compare {
bool operator()(const Item* a, const Item* b) {
if (a->score != b->score) return a->score > b->score;
return a->id < b->id;
}
};
};
因为set允许您定义自己的比较方法,所以可以按如下方式使用它。
std::set<Item*, Item::compare> sortedItems;
这应该允许您的类Item使用set
答案 1 :(得分:2)
set<T>
实施想要致电a < b
,其中a
和b
是T
类型的对象。只要该呼叫有效,该集合就不关心;它可以是一个非静态成员函数,它接受一个参数,一个带有两个参数的静态成员函数,或一个带两个参数的自由函数:
class Item {
public:
bool operator<(const Item& rhs) {
return score == rhs.score ? id < rhs.id : score < rhs.score;
}
static bool operator<(const Iterm& lhs, const Item& rhs) {
return lhs.score == rhs.score ? lhs.id < rhs.id : lhs.score < rhs.score;
}
};
bool operator<(const Item& lhs, const Item& rhs) {
return lhs.score == rhs.score ? lhs.id < rhs.id : lhs.score < rhs.score;
}
这三个中的任何一个都没关系。当然,如果你写两个或更多,你会有歧义。