У меня есть класс, и указатели на объекты этого класса должны быть помещены в std::set
, Я хочу определить компаратор внутри класс. Я видел несколько решений, где либо определяется отдельный класс (я думаю, он называется функтором), либо определяется структура, которая перегружает operator()
, Я хочу избежать этого стандартного кода и хочу определить компаратор как член самого класса, что-то вроде Java compareTo()
метод.
Допустим, мой класс что-то вроде:
class Item {
private:
int id;
float score;
.....
public:
// Rest of the methods and setters/getters
}
Я хочу определить компаратор таким образом, чтобы указатель на объект, имеющий более высокий балл, размещался первым в наборе. Если счет для двоих одинаков, тогда ставится тот, у кого более низкий идентификатор. Я предполагаю, что код будет примерно таким, но я не очень хорошо понял эту часть, пожалуйста, исправьте меня (я хотел бы, чтобы это было помещено внутри самого класса):
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 ++. Спасибо!
это решение вдохновлено этим ответ.
#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<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;
}
Любой из этих трех в порядке. Конечно, если вы напишите два или более из них, вы получите двусмысленность.