2

我有一个类,指向这个类的对象的指针需要放在一个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++ 也很陌生。谢谢!

4

2 回答 2

5

这个解决方案的灵感来自这个答案

#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

于 2012-10-11T14:13:33.740 回答
2

set<T>实现想要调用a < bwhereabare 类型的对象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;
}

这三个中的任何一个都可以。当然,如果你写了两个或更多,你会得到模棱两可的。

于 2012-10-11T14:07:59.047 回答