在c++中,set可以自动对值进行排序,所以我只需要插入它们。
对于自定义结构,我只需要定义运算符>以及<,像这样:
#include <iostream>
#include <cmath>
#include <set>
using namespace std;
struct A {
A(int a) : a_(a) {}
friend bool operator <(const A& shot1, const A& shot2) {
return shot1.a_ < shot2.a_;
}
friend bool operator >(const A& shot1, const A& shot2) {
return shot1.a_ > shot2.a_;
}
int a_;
};
int main(int argc, char** argv) {
std::set<A> s;
A a1(10), a2(11), a3(9);
s.insert(a1);
s.insert(a2);
s.insert(a3);
for (auto i : s) {
cout << i.a_ << endl; // 9, 10, 11, it's sorted.
}
}
这是可行的,但当我有一个自定义结构时,它非常重,所以复制构造函数会很昂贵。我想把保存指针设置成这样:
#include <iostream>
#include <cmath>
#include <set>
using namespace std;
struct A { // NOTICE HERE: A's contructor is very heavy
A(int a) : a_(a) {}
friend bool operator <(const A& shot1, const A& shot2) {
return shot1.a_ < shot2.a_;
}
friend bool operator >(const A& shot1, const A& shot2) {
return shot1.a_ > shot2.a_;
}
int a_;
};
int main(int argc, char** argv) {
std::set<A*> s;
A a1(10), a2(11), a3(9);
s.insert(&a1);
s.insert(&a2);
s.insert(&a3);
for (auto i : s) {
cout << i->a_ << endl; // 10, 11, 9, not sorted!!!!!!!
}
}
但是我认为set排序函数失败了,那么,当set值是指针时,我该如何使它工作呢?
集合不再是对象A
,而是指针A*
。因此,集合的默认排序是在指针转换为整数时执行的,它是在内存中对其位置进行排序。为了避免这种情况,需要一个自定义的比较运算符,该运算符绕过所需的实例排序。
您可以定义自己的比较函数,如下例所示。
这个想法是创建一个函子:一个有运算符括号的结构,并实现所需对象之间的比较(小于(:
bool operator()(Obj a, Obj b); //Less comparison.
然后,类可以在模板中使用集合:
#include <iostream>
#include <cmath>
#include <set>
using namespace std;
struct A { // NOTICE HERE: A's contructor is very heavy
A(int a) : a_(a) {}
friend bool operator <(const A& shot1, const A& shot2) {
return shot1.a_ < shot2.a_;
}
friend bool operator >(const A& shot1, const A& shot2) {
return shot1.a_ > shot2.a_;
}
int a_;
};
struct Comp
{
bool operator()(const A* a, const A* b)
{
if (a && b)
{
return *a < *b;
}
return a<b;
}
};
int main(int argc, char** argv) {
std::set<A*, Comp> s;
A a1(10), a2(11), a3(9);
s.insert(&a1);
s.insert(&a2);
s.insert(&a3);
for (auto i : s) {
cout << i->a_ << endl; // 10, 11, 9, not sorted!!!!!!!
}
}
有关如何为集合创建自定义比较器的更多信息:
使用自定义std::设置比较器