我有一组指针,我想以确定的方式迭代。显然,如果我使用set的默认排序顺序,这将基于指针内存地址,每次程序运行时它们可能不同。所以我定义了一个我想要使用的自定义比较器,但是我不想更改集合的模板化类型(因为它在代码中的一百万个位置使用),所以我想将一个比较器对象传递给设置从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;
}
所以我的问题是,我忘了做什么?
答案 0 :(得分:3)
比较器对象的std::set
构造函数的形式参数类型为Compare const&
,其中Compare
是模板参数。
因此,即使set对象保留了对实际比较器对象的引用(而不是复制它),它也会被视为类型Compare
,您默认为std::less
。
由于std::less
是非多态的,所以std::less::operator()
被调用,而不是operator()
TestClassLessThan
{。}}。
所以缺点是,“你做不到”。
或者更确切地说,您可以像代码所示,但不会改变任何行为。
要更改比较对象,您必须将其他Compare
类型指定为模板参数。
这是你想要避免的,但对不起,没有办法(我知道)。
干杯&amp;第h。,
答案 1 :(得分:3)
以上所有内容均有效。 一种可能的解决方案是使用模板特化来自定义std :: less本身:
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的默认模板比较器获取自定义行为。
根据您构建系统的方式,如果该集合“在一百万个地方使用”并且自定义std :: less不能始终可用,则可能会出现问题。
答案 2 :(得分:1)
这不是使用比较器设置的方法。 std :: less的operator()不是虚函数,不会被覆盖。
而是使用这种方式进行初始化,它就可以解决问题。
set<TestClass*, TestClassLessThan> testSet, testSet2;
为此,比较函数应该接受const指针而不是指向const的指针。为了安全起见,您可以将其更改为
// functor for operator<
bool operator()(const TestClass* const&_Left, const TestClass* const&_Right) const
{
cout << "comparing";
// apply operator< to operands
return (_Left->getId() < _Right->getId());
}