如何使用常量getter函数对std::set进行排序

5

我有一个std::set容器,其中元素是以下类的对象:

class LaneConnector {
public:

    const Lane* getLaneFrom() const {
        return From;
    }
    const Lane* getLaneTo() const {
        return To;
    }

private:

    Lane* From;
    Lane* To;
}

我的比较函数如下所示:
struct MyLaneConectorSorter {
  bool operator() (LaneConnector * c, LaneConnector * d)
  {
      Lane* a = const_cast<Lane*>(c->getLaneFrom());
      Lane* b = const_cast<Lane*>(d->getLaneFrom());
      return (a->getLaneID() < b->getLaneID());
  }
} myLaneConnectorSorter;

现在当我尝试对集合中的元素进行排序时,可以使用以下方法:
//dont panic, the container just came through a const_iterator of a std::map :)
const std::set<LaneConnector*> & tempLC = (*it_cnn).second;
std::sort(tempLC.begin(), tempLC.end(), myLaneConnectorSorter);

我遇到了一系列错误,从以下几行开始,希望您能帮助我解决这个问题。谢谢:

/usr/include/c++/4.6/bits/stl_algo.h: In function ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = std::_Rb_tree_const_iterator<LaneConnector*>, _Compare = {anonymous}::MyLaneConectorSorter]’:
/home/.../dev/Basic/shared/conf/simpleconf.cpp:1104:65:   instantiated from here
/usr/include/c++/4.6/bits/stl_algo.h:5368:4: error: no match foroperator-’ in ‘__last - __first’
/usr/include/c++/4.6/bits/stl_algo.h:5368:4: note: candidates are:
/usr/include/c++/4.6/bits/stl_iterator.h:321:5: note: template<class _Iterator> typename std::reverse_iterator::difference_type std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:378:5: note: template<class _IteratorL, class _IteratorR> typename std::reverse_iterator<_IteratorL>::difference_type std::operator-(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/stl_bvector.h:181:3: note: std::ptrdiff_t std::operator-(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
/usr/include/c++/4.6/bits/stl_bvector.h:181:3: note:   no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<LaneConnector*>’ to ‘const std::_Bit_iterator_base&’
1个回答

10

首先,你不能对std::set进行排序。它是一个有序结构,在构造或插入时进行排序。

其次,你可以使用自定义的排序函数构造一个std::set,并通过使其接受const指针来避免不必要的const_casts

struct MyLaneConectorSorter {
  bool operator() (const LaneConnector* lhs, const LaneConnector* rhs) const
  {
    // you may want to put some null pointer checks in here
    const Lane* a = lhs->getLaneFrom();
    const Lane* b = rhs->getLaneFrom();
    return a->getLaneID() < b->getLaneID();
  }
};

并且可以像这样实例化集合:

std::set<LaneConnector*, MyLaneConectorSorter> s(MyLaneConectorSorter());

或者,如果您想从不同的集合构建它,并按不同的顺序排列,

std::set<LaneConnector*> orig = ..... ;
....
std::set<LaneConnector*, MyLaneConectorSorter> s(orig.begin(), orig.end(), MyLaneConectorSorter());

2
我总是觉得直接重载 bool operator<(const LaneConnector & _rhs) 更容易/更简洁。 - Rollie
@rahman,我在函数对象中发现了一个小错误,我认为已经修复了。但是Lane::getLaneID()必须是一个const方法。 - juanchopanza
好的,插入新集合时出现了问题。它只插入了一个(而不是14个),我应该将其移到另一个线程吗? - rahman
@juanchopanza:但是您不能调用需要引用传递的方法并将它们传递指针。此外,那个 operator() 甚至无法编译。当然,如果您修复它,我很乐意取消我的投票。 - Gorpik
1
@Gorpik 谢谢,已经修复了。我误读了你的第一条评论。 - juanchopanza
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接