2009-05-18 67 views
0

的排序函數重新定義順序我有以下的數據結構:幾個函子用於矢量

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

};

我用的是仿訂單以下列方式確定當構造():

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

這樣,當使用仿函數命令(初始化我的數據myEdges_排列)。 現在我想使用完全不同的條件來安排數據sweepEvents(它與myEdges_具有相同的類型,使用C++向量中的預定義數據類型),也就是說,我不想使用函數getSlope(...)函數computeDet(...)用於sweepEvents。 所以我想我仍然需要其他仿函數來重新定義矢量數據類型的sort()的<?所以,我會寫一個新的算符order1(),其中我用computeDet(...)計算出的數據,然後我調用sort我sweepEvents數據類型:

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

我不知道,如果這是很好的解決方案?如果我爲函子使用不同的名字,我可以用幾種方式重新定義<? 有人有一些建議,我會很感激。 謝謝你, madalina

沒有兩個仿函數不使用任何公共代碼。 我已經寫了第二函子insede的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

回答

4

如果你有2個不同的排序標準,那麼你應該有2個不同的函數。

給他們有意義的名字,如:

OrderBySlopes和OrderByXYZ

如果2個仿函數使用一些常用的代碼,你可以重構了這一點。即成基類

0

什麼Glen說。

如果你真的確實堅持讓一個函數執行雙重任務,你可以依靠不同的參數類型來重載operator()的兩個版本。

0

您的orderDet::operator()需要三個參數。 std::sort只需要兩個比較兩個值。

一個解決方案可能是邊緣矢量添加爲仿函數的成員:

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。 接下來,最好定義一個包含「第一個」和「第二個」點的結構,而不是僅使用前兩個點的非常通用的向量。它會讓你的代碼更具可讀性。

問候。

+0

是的,它的工作。謝謝。 (我在我的代碼中使用了typedef,我也應該在這裏使用它) – madalina 2009-05-19 09:43:36