2012-04-12 115 views
0

我需要爲我的Note對象使用unordered_multimap,而這些鍵將是我的對象的measureNumber成員。我試圖執行它as shown here但我卡住了。unordered_multimap用法和操作符覆蓋

首先,我不明白爲什麼我必須覆蓋operator==才能使用它。我也很困惑,爲什麼我需要一個哈希以及如何實現它。 In this example here,這兩件事都沒有完成。

因此,基於第一個例子,這是我有:

class Note { 
private: 
    int measureNumber; 
public: 
    inline bool operator== (const Note &noteOne, const Note &noteTwo); 
} 

inline bool Note::operator ==(const Note& noteOne, const Note& noteTwo){ 
    return noteOne.measureNumber == noteTwo.measureNumber; 
} 

我不知道如何實現,雖然散列部。有任何想法嗎?

回答

1

std::multimap基於排序的二叉樹,該排序的二叉樹使用小於操作來排序節點。

std::unordered_multimap基於散列表,它使用散列和相等操作來組織節點而不對它們進行排序。

排序或哈希是基於關鍵值。如果對象是鍵,那麼您需要定義這些操作。如果鍵是預定義的類型,如intstring,那麼您不必擔心它。

您的僞代碼的問題是measureNumber是私人的,因此Note的用戶無法輕易指定地圖的密鑰。我會建議讓measureNumber公開或重新考慮設計。 (是衡量號真是個好鍵值?我猜這是簡譜。)

std::multimap< int, Note > notes; 
Note myNote(e_sharp, /* octave */ 3, /* measure */ 5); 
notes.insert(std::make_pair(myNote.measureNumber, myNote)); 

對象可以是鍵值的同時,如果使用std::multisetstd::unordered_multiset,其中你會想要定義運算符重載(也可能是散列)。如果operator==(或operator<)是成員函數,則左側將變爲this,右側將成爲唯一參數。通常這些功能應該是非會員朋友。所以那麼你會有

class Note { 
private: 
    int measureNumber; 
public: 
    friend bool operator< (const Note &noteOne, const Note &noteTwo); 
} 

inline bool operator <(const Note& noteOne, const Note& noteTwo){ 
    return noteOne.measureNumber < noteTwo.measureNumber; 
} 

這個類可以與std::multiset一起使用。要執行基本查找,可以使用未初始化的值構造一個虛擬對象,但measureNumber除外 - 這僅適用於簡單對象類型。

+0

我將如何構建多圖,像這樣? 'multimap noteMap;'運算符<'函數的定義是在頭文件還是在實現文件中? – networkprofile 2012-04-12 01:29:04

+0

@Sled好的,我希望這是你要找的。現在需要走了,祝你好運! – Potatoswatter 2012-04-12 01:41:02

+0

我有getter和setter爲measureNumber,所以這不是一個真正的問題。我現在認識到,除了特定的筆記之外很難刪除,因爲它們是通過measureNumber進行映射的,但我需要這種模型進行實時合成,因爲我需要儘快地通過度量來找到筆記,這看起來像是一個迄今爲止的好方法。 (我不得不多次改變事情)非常感謝您的幫助! – networkprofile 2012-04-12 01:56:09

1

我需要爲我的Note對象使用unordered_multimap,並且鍵 將是我的對象的measureNumber成員。

行 - 我不知道你是否multisetunordered_multisetmultimap,或unordered_multimap後是。我知道你的標題是指unordered_multimap,但你提供的鏈接導致unordered_multiset。在選擇容器時應考慮多種因素,但如果不進行分析就能獲得最佳性能的二次猜測是一項危險的業務。

我不明白爲什麼我必須覆蓋運算符==才能使用它。 我也困惑爲什麼我需要一個哈希以及如何實現它。 在這個例子中,這兩件事都沒有完成。

您需要operator==std::hash,因爲它們可以通過unordered_multimapunordered_multiset內部使用。在您鏈接的示例中,密鑰類型爲int,因此operator==std::hash<int>已經定義。如果你選擇使用Note作爲關鍵,你必須自己定義這些。


我建議你開始用multiset,如果你並不需要經常更換的元素。如果你希望能夠更改Note s沒有刪除和插入,我建議刪除measureNumber作爲Note成員和使用multimap<int, Note>

如果您覺得​​版本的容器更適合您的需求,您仍然有setmap的選擇。如果您選擇unordered_multimap<int, Note>(已從Note中刪除measureNumber),則正如在您的鏈接示例中,密鑰爲int。所以你不必定義任何特殊的工作。如果您選擇保留measureNumber作爲Note的成員並使用unordered_multiset<Note>,那麼Note是關鍵,因此您需要做進一步的工作,例如,

#include <functional> 
#include <unordered_set> 

class Note; // Forward declaration to allow specialisation of std::hash<> 

namespace std { 
template<> 
class hash<Note> { 
public: 
    size_t operator()(const Note &) const; // declaration of operator() to 
              // allow befriending by Note 
}; 
} 

class Note { 
private: 
    int measureNumber; 
public: 
    // functions befriended to allow access to measureNumber 
    friend bool operator== (const Note &, const Note &); 
    friend std::size_t std::hash<Note>::operator()(const Note &) const; 
}; 

inline bool operator== (const Note &noteOne, const Note &noteTwo) { 
    return noteOne.measureNumber == noteTwo.measureNumber; 
} 

std::size_t std::hash<Note>::operator()(const Note &note) const { 
    return std::hash<int>()(note.measureNumber); 
} 

這可以讓您創建和使用std::unordered_multiset<Note>。但是,我不確定這個是否真的是你需要的;你甚至可以發現排序的std::vector<Note>最適合你。進一步的研究和想法,你將如何使用你的容器與分析應該給出最好的答案。