几个仿函数,用于重新定义向量排序函数的顺序

时间:2009-05-18 14:24:41

标签: c++

我有以下数据结构:

typedef vector< vector<int> > MxInt2d;
typedef vector< vector<double> > MxDouble2d;

 class QSweep{   
 public:
 ....
 static MxDouble2d myPoints_;
 MxInt2d myEdges_;
 MxInt2d sweepEvents;

 class order{
 public:
    bool operator() (const vector<int>& edge1, const vector<int>& edge2){
            return (myPoints_[edge1[0]][0]<myPoints_[edge2[0]][0])|| 
                       (myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&& 
                        myPoints_[edge1[0]][1]<myPoints_[edge2[0]][1]) 
                   ||
                    (myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&& 
                         myPoints_[edge1[0]][1]==myPoints_[edge2[0]][1]&& 
                     getSlope(myPoints_[edge1[0]][0],myPoints_[edge1[0][1],  
                                  myPoints_[edge1[1]][0],myPoints_[edge1[1]][1])
                     <
                         getSlope(myPoints_[edge2[0][0],myPoints_[edge2[0][1],    
                                  myPoints_[edge2[1]][0],myPoints_[edge2[1]][1]));
                    }
};
static double getSlope(double a, double b, double c, double d);
static double computeDet(double a, double b, double c, double d, double x, double y);

};

在按以下方式定义构造函数时,我使用functor for order():

 QSweep::QSweep(const MxDouble2d& myPoints, const MxInt2d& myEdges){ 
....
    //code here for initializing myPoints_, myEdges_
sort(myEdges_.begin(),myEdges_.end(),order());
 }

这样,我的数据myEdges_在使用仿函数order()初始化时排列。 现在我想使用完全不同的标准来安排数据sweepEvents(与使用C ++向量中的预定义数据类型的myEdges_具有相同的类型),即我不想使用函数getSlope(...)但函数scanEvents的computeDet(...)。 所以我在想我还需要其他仿函数来重新定义&lt;对于矢量数据类型的sort()对吗?所以我必须编写一个新的函子order1(),其中我使用computeDet(...)计算的数据,然后我在sweepEvents数据类型上调用sort:

 sort(sweepEvents.begin(),sweepEvents.end(),order1());

我不确定这是不是很好的解决方案?我能以多种方式重新定义吗?如果我为仿函数使用不同的名称? 有人有一些建议我会非常感激。 先感谢您, madalina

这两个仿函数没有使用任何通用代码。 我已经编写了第二个编写器,将QSweep类编译为:

 class orderDet{
public:
    bool operator() (const vector<int>& edgeSW1, const vector<int>& edgeSW2   
                              ,const vector<int>& edgeC){
        return  
          (
          computeDet(myPoints_[edgeSW1[0]],myPoints_[edgeSW1[1]],myPoints_[edgeC[0]]) 
           < 
          computeDet(myPoints_[edgeSW2[0]],myPoints_[edgeSW2[1]],myPoints_[edgeC[0]])
           );
  }}

我称之为:

 sort(sweepEvents.begin(), sweepEvents.end(), orderDet());

但是我收到了以下编译错误:

 error: no match for call to '(QSweepComplete::orderDet) (std::vector<int,  
 std::allocator<int> >&, std::vector<int, std::allocator<int> >&)'
 ./QSweepComplete.h:68: note: candidates are: bool 
 QSweepComplete::orderDet::operator()(const std::vector<int, std::allocator<int>>&,   
 const std::vector<int, std::allocator<int> >&, const std::vector<int, 
 std::allocator<int> >&)

我猜测参数不匹配,因为orderDet(....,edgeC)的第三个参数不是sweepEvents列表的一部分,因为其他的是变量myEdges _...的一部分。 也许有人可以就如何实现这个仿函数给我一些建议?

提前谢谢你。 最好的祝愿, madalina

3 个答案:

答案 0 :(得分:4)

如果您有2个不同的排序标准,那么您应该有2个不同的仿函数。

给他们有意义的名字,例如:

OrderBySlopes和OrderByXYZ

如果2个仿函数使用一些通用代码,则可以重构它。即进入基类

答案 1 :(得分:0)

Glen说了什么。

如果你真的坚持让一个函数执行双重任务,你可以依赖不同的参数类型来重载两个版本的operator()。

答案 2 :(得分:0)

你的orderDet::operator()有三个参数。 std::sort只需要两个来比较两个值。

解决方案可能是将edge矢量添加为您的仿函数成员:

struct orderDet {
    const vector<int>& edges;
    orderDet( const vector<int>& edges ):edges(edges){};

    bool operator()( const vector<int>& v1, const vector<int>& v2 ) const {
       ....
    }
 };

顺便说一句,如果你希望人们在阅读代码时理解你的代码,我宁愿认为你应该使用typedef作为内部向量而不是外部向量。 接下来,最好定义一个包含'first'和'second'点的结构,而不是一个只使用前两个点的非常通用的向量。它也会使你的代码更具可读性。

问候。