Multiple functors to override the sort order of a vector function

I have the following data structure:

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);

      

};

I am using a functor for order () when defining a constructor like this:

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

      

This way my data myEdges_ is located on initialization using functor order (). Now I want to order the sweepEvents data (which is the same type as myEdges_ using the predefined data type from the C ++ vector) using completely different criteria, that is, I don't want to use the getSlope (...) function, but the computeDet function (...) for sweepEvents. So I thought I still need another functor to override <sort () for the vector data type? So I would have to write a new functor order1 () in which I use the data computed with computeDet (...) and then I call the sort on my sweepEvents data types:

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

      

I'm not sure if this is a good solution? can i override in several ways <if i use different names for the functor? Anyone have any suggestions, I would really appreciate it. Thanks in advance, Madalina

There are no two functors that don't share any common code. I wrote a second functor that contains the QSweep class:

 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]])
           );
  }}

      

and I named it as follows:

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

      

But I got the following compilation error:

 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> >&)

      

I'm guessing the parameter doesn't match as the third parameter orderDet (...., edgeC) is not part of the sweepEvents list as the others are part of myEdges _... Maybe you can give me some advice on how to implement this functor?

thank you in advance. best wishes Madalina

0


a source to share


3 answers


If you have 2 different sorting criteria, then you should have 2 different functors.

Give them meaningful names, for example:



OrderBySlopes and OrderByXYZ

If the 2 functors share some common code, you can refactor that. those. to base class

+4


a source


What Glen said .



If you really insist that one function does double work, you can rely on having different parameter types to overload the two versions of the () operator.

0


a source


Yours orderDet::operator()

takes three arguments. The parameter std::sort

only requires two comparisons of the two values.

The solution might be to add an edge vector as a member of your functor:

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

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

      

By the way, if you want people to understand your code when they read it, I would rather think that you should use a typedef for your inner vector rather than the outer one. Also, it is better to define a structure containing a "first" and "second" point than a very general vector in which you only use the first two points. This will make your code more readable.

Sincerely.

0


a source







All Articles