0

我需要unordered_multimap为我的 Note 对象使用 an,键将是measureNumber我的对象的成员。我正在尝试按照此处所示的方式实现它,但我被卡住了。

首先,我不明白为什么我必须先覆盖operator==它才能使用它。我也对为什么需要哈希以及如何实现它感到困惑。在这个例子中,这两件事都没有完成。

所以基于第一个例子,这就是我所拥有的:

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

我不知道如何实现哈希部分。有任何想法吗?

4

2 回答 2

0

std::multimap基于排序二叉树,它使用小于运算对节点进行排序。

std::unordered_multimap基于哈希表,它使用哈希和相等操作来组织节点而不对它们进行排序。

排序或散列基于键值。如果对象是键,那么您需要定义这些操作。如果键是预定义类型,例如intor string,那么您无需担心。

您的伪代码的问题measureNumber是私有的,因此用户Note无法轻松指定地图的密钥。我建议measureNumber公开或重新考虑设计。(小节数真的是一个很好的关键值吗?我猜这是乐谱。)

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

如果使用or ,对象可以同时是键值,在这种情况下,您需要定义运算符重载(可能还有哈希)。如果(or ) 是成员函数,则左侧变为唯一参数,右侧变为唯一参数。通常这些功能应该是非会员朋友。那么你会有std::multisetstd::unordered_multisetoperator==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- 这仅适用于简单对象类型。

于 2012-04-12T01:16:19.153 回答
0

我需要为我的 Note 对象使用 unordered_multimap,键将是我的对象的 measureNumber 成员。

好的 - 我不确定你是在追求multiset, unordered_multiset, multimap, 还是unordered_multimap. 我知道您的标题指的是unordered_multimap,但您提供的链接指向unordered_multiset. 在选择容器时应该考虑很多因素,但是在没有分析的情况下事后猜测哪个性能最好是有风险的。

我不明白为什么我必须先覆盖 operator== 才能使用它。我也对为什么需要哈希以及如何实现它感到困惑。在这个例子中,这两件事都没有完成。

您需要operator==andstd::hash因为它们在内部被unordered_multimapand使用unordered_multiset。在您链接到的示例中,键的类型为int,因此operator==std::hash<int>已经定义。如果选择Note用作键,则必须自己定义这些。


multiset如果您不需要经常更改元素,我建议您从 a 开始。如果您确实希望能够在Note不删除和插入的情况下更改 s,我建议您将measureNumber其作为成员删除Note并使用multimap<int, Note>.

如果您觉得unordered_您的容器版本更适合您的需求,您仍然可以选择setvs。map如果您选择unordered_multimap<int, Note>(已从 中删除measureNumberNote,那么与您的链接示例一样,键是int。因此,您不必为此定义任何特殊的东西。如果您选择保留measureNumberNote使用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>. 但是,我不确定这是否真的是您需要的;您甚至可以发现 sortedstd::vector<Note>最适合您。关于如何使用容器以及分析的进一步研究和思考应该会给出最好的答案。

于 2012-04-12T03:11:50.533 回答