自定义比较器通过显式构造函数排序std :: set [英] Custom comparator via explicit constructor for sorting std::set
问题描述
我有一组指针,我想以确定性的方式迭代。显然,如果我使用默认排序顺序设置,这将基于指针内存地址,这可能是不同的每次程序运行。所以我定义一个自定义比较器,我想使用,但我不想改变集合的模板类型(因为它在代码中的一百万个地方使用),所以我想传递一个比较器对象到设置构造函数,它源于std :: less
I've got a set of pointers which I would like to iterate over in a deterministic manner. Obviously if I use the default sort order for set, this will be based on the pointers memory addresses which can be different each time the program runs. So I define a custom comparator which I want to use, but I don't want to change the templated type of the set (because it's used in a million places in the code), so I want to pass in a comparator object to the set constructor which is derived from std::less
class TestClass
{
public:
TestClass(int id_) : id(id_) {}
~TestClass() {}
int getId() const { return id;}
void setId(int id_) { id = id_; }
private:
int id;
};
struct TestClassLessThan : public std::less<TestClass*>
{ // functor for operator<
bool operator()(const TestClass* &_Left, const TestClass* &_Right) const
{ // apply operator< to operands
return (_Left->getId() < _Right->getId());
}
};
int main(void)
{
TestClassLessThan comp;
set<TestClass*> testSet(comp), testSet2(comp);
TestClass* obj1 = new TestClass(1);
TestClass* obj2 = new TestClass(2);
testSet.insert(obj1);
testSet.insert(obj2);
TestClass* obj = *(testSet.begin());
cout << "First run" << endl;
BOOST_FOREACH(TestClass* o, testSet) // expecting 1,2 - get 1,2
cout << o->getId() << endl;
// now change the ordering (based on id) and insert into a new set in the same order
obj1->setId(3);
testSet2.insert(obj1);
testSet2.insert(obj2);
cout << "Second run" << endl;
BOOST_FOREACH(TestClass* o, testSet2) // expecting 2,3 - get 3,2
cout << o->getId() << endl;
delete obj1;
delete obj2;
}
因此我的问题是,我忘记了什么?
So my question is, what have I forgotten to do?
推荐答案
以上所有内容都有效。
一个可能的解决方案是使用模板专门化来自定义std :: less本身:
All the above is valid. A possible solution is to customise std::less itself using template specialisation:
namespace std
{
template<>
struct less< TestClass*>
{ // functor for operator<
public:
bool operator()( TestClass* const &_Left, TestClass* const &_Right) const
{ // apply operator< to operands
return (_Left->getId() < _Right->getId());
}
};
}
然后使用std :: set的默认模板比较器。
You then get your custom behaviour using the default template comparator for std::set.
根据您的系统构建方式,如果集合在一百万个地方使用并且自定义std :: less不是始终可用,则可能会有问题。
Depending on how you build your system, you may have problems if the set is "used in a million places " and the custom std::less is not consistently available.
这篇关于自定义比较器通过显式构造函数排序std :: set的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!