2010-10-08 41 views
4

目前我正在學習標準模板庫(STL)。這個程序爲什麼重載()運算符?

在這個程序中,我將一些長的值存儲在關聯容器中,然後根據單元的位置(根據單元位置的數字)對它們進行排序。

代碼:

#include <iostream> 
#include <set> 
#include <functional> 

using namespace std; 

class UnitLess 
{ 
public: 
    bool operator()(long first, long second) 
    { 
     long fu = first % 10; 
     long su = second % 10; 

     return fu < su; 
    } 
}; 

typedef set<long, UnitLess> Ctnr; 

int main(void) 
{ 
    Ctnr store; 

    store.insert(3124); 
    store.insert(5236); 
    store.insert(2347); 
    store.insert(6415); 
    store.insert(4548); 
    store.insert(6415); 

    for(Ctnr::iterator i = store.begin(); i != store.end(); ++i) 
    { 
     cout << *i << endl; 
    } 
} 

但我不明白,爲什麼我們的教授重載()運算符?

謝謝。

+1

彷彿重載'()'操作被稱爲在例如在所有它不會出現。也許它會在後面的練習中介紹? – 2010-10-08 08:32:46

+2

是它被稱爲時'的std :: set'試圖插入按排序順序(二進制謂詞) – Benoit 2010-10-08 08:35:03

+0

@格雷格Hewgill運算符()元件被稱爲內部時,它執行store.insert(一些長值); – Searock 2010-10-08 08:35:34

回答

7

類的目的是實現排序以一定的方式在集合中的元素的功能。這被稱爲謂詞。

它被實現爲一個仿函數,即允許函數操作符用於一個對象(這是std :: set在引擎蓋下)。這樣做是STL和類似代碼調用自定義對象的常用方式。 (函數指針比

所以它的使用這樣的功能對象(又名仿函數)更多的限制:

Unitless functor; 

functor(123, 124); // returns true or false 

的std ::集是一個排序二叉樹,所以它調用無單位的() - 運營商在每次插入幾次,以確定每個長值應該去。

嘗試編譯並把一些的printf /性病::法院在那裏,看看會發生什麼。

而且,請注意回調像這樣(即當你看不到你的代碼的調用)在你的學習曲線開始時會令人感到恐懼和困惑。

  • 然後,你習慣了它,並全部使用它們,因爲它們整齊。
  • 然後你的代碼再次變得可怕又令人困惑,並且避免它們像瘟疫一樣。
  • 然後,你成爲一個管道磁帶程序員,只在適當的地方使用它們,但從來沒有在別處使用它們。

;)

+0

+1非常感謝。 – Searock 2010-10-08 08:59:13

7

UnitLess是一個binary predicate,需要在STL中使用兩個參數進行調用。

通過重載函數調用運算符UnitLess該類型的實例可以像使用兩個longs並返回bool的函數一樣使用。

UnitLess f; 
f(5, 10); 

相當於

bool f(long first, long second) 
{ 
    long fu = first % 10; 
    long su = second % 10; 

    return fu < su; 
} 
f(5, 10); 
+0

對不起,我初學者,我不明白你想說什麼:( – Searock 2010-10-08 08:33:59

+1

@ Space_C0wb0y運算符(),當它執行store.insert(一些長期值)被內部調用; – Searock 2010-10-08 08:36:47

+0

爲什麼你需要提供一個謂詞對象?IIRC,'的std ::設置'將使用默認構造謂詞(即'強的鬆()')。在這裏,'UnitLess'是默認施工的。此外,如果你沒有提供謂詞_object_,你會'的std ::設置'不這樣做,這顯然不能用'的std ::少()' – MSalters 2010-10-08 08:42:22

2

他已經實施了用於標準自定義比較::設置,只有比較單位,即量模10.因爲的std ::集是一個模板,它只是試圖調用的東西看起來像一個函數,不管它是否是一個函數。通過重載operator(),你可以使它像一個函數一樣工作。

這樣做實際上可以在某些情況下是非常強大的,因爲一個結構/類可以存儲狀態,以及額外的參數。整個boost :: function/boost :: bind是基於這樣做的(每次你不需要創建一個類)。

在實際的例子編碼有可能是一個略有瑕疵的演習是簡單地通過單位對它們進行排序,但它很可能消除具有相同的單位,但實際上並沒有重複號碼。在你的示例代碼中沒有這樣的例子(你有一個重複的,但這是整個值的重複)。如果除了4548之外還有3478個,Set比較器會認爲它們是相同的,並且不允許重複。

順便說一句,我不知道集是什麼,我會叫「聯想」的容器,它指的是鍵 - 值對。在設置中沒有關聯的值,只是鍵。

還有一點:運營商()應該是常數。

+0

你確定它不是'Associative Container'嗎? http://www.sgi.com/tech/stl/set.html表示它是'Sorted Associative Container'。 – Searock 2010-10-08 10:04:50

+0

sgi.com的文檔編輯認爲它是一個關聯容器,但似乎並不匹配,在維基百科即http://en.wikipedia.org/wiki/Associative_array描述,在這裏似乎應該有與該鍵關聯的一些值。你可以說一把鑰匙把價值映射到自己身上。當然,std :: set的實現者和任何其他語言的等價物可能希望使用它們用於map的相同實現,即樹。 – CashCow 2010-10-11 08:17:19