2009-07-25 55 views
4

如果我想排序兩種類型的其持有的變量之一的UDT的載體,是有可能的標準庫的排序要做到這一點還是我需要寫我自己的排序功能。標準庫的排序和用戶定義類型

例如,如果你有

struct MyType{ 
int a; 
int b; 
}; 

vector<MyType> moo; 

// do stuff that pushes data back into moo 

sort(moo.begin(), moo.end()) // but sort it by lowest to highest for a, not b 

因此,這是可能的使用STDLIB排序?謝謝。

回答

8

它可以使用標準的功能,如果你的類型實現了"bool operator < (...) const"和拷貝構造函數(編譯器生成的或自定義)。

struct MyType { 
    int a; 
    int b; 
    bool operator < (const MyType& other) const { 
     ... // a meaningful implementation for your type 
    } 
    // Copy constructor (unless it's a POD type). 
    MyType(const MyType &other) 
     : a(other.a), b(other.b) { } 
    // Some other form of construction apart from copy constructor. 
    MyType() 
     : a(0), b(0) { } 
}; 

或者,也可以通過一個排序函數(或仿函數),爲第三個參數sort()代替實施操作者"<"

bool type_is_less(const MyType& t1, const MyType& t2) { ... } 
... 
std::sort(c.begin(), c.end(), type_is_less); 

這是在下列情況下有效:

  1. 你不希望實現無論出於何種原因操作"<"
  2. 你需要排序的內置或指針類型的容器爲此您不能重載操作員。
  3. 你想使用不同排序順序進行排序。例如:有時候你需要一個結構,其中第一個姓氏成員按姓氏排序,其他時間按姓氏排序。兩個不同的函數(或函子)使這樣的選項變得微不足道。
+1

另一種選擇是專注'的std :: less`你的類型。這樣你就不必每次都傳遞函數(例如,因爲確實有一個合理的定義),但是你的類型不會得到`operator <`。 – 2009-07-25 06:02:32

3

有三種方法可以做到這一點:

你可以重載operator<爲你的類:

bool operator<(const MyType& lhs, const MyType& rhs) {return lhs.a<rhs.a;} 

這樣做,如果你想根據b對它們進行排序的缺點,你運氣不好。

你也可以專門std::less你的類型。這使std::sort工作(和其他的東西,如使用該類型作爲地圖中的關鍵),沒有劫持operator<這個意思。但是,它仍然劫持了a的通用比較語法,而您可能會在代碼中的其他位置根據b比較您的類型。

或者你也可以寫你自己的比較是這樣的:

struct compare_by_a { 
    bool operator()(const MyType& lhs, const MyType& rhs) const 
    {return lhs.a<rhs.a;} 
}; 

(注:該const後的運營商並非絕對必要我仍然認爲這是良好的作風,雖然)這使得常規 - 目的比較手段undefined;所以如果某些代碼想要在不知道的情況下使用它們,則編譯會發出錯誤並使您意識到它。您可以選擇並明確地使用此比較器或其他比較器,以便隨時進行比較。

相關問題