我如何使用C ++ unordered_set自定义类?

问题描述 投票:6回答:3

我怎么能存储在一个unordered_set一个类的对象?我的程序需要经常检查,如果在此unordered_set存在的对象,如果确实如此,那么做对象的某些更新。

我在网上查找关于如何使用unordered_set,但遗憾的是大多数的教程是关于使用它intstring类型。但我怎么可以用它在一类?我如何定义一个散列函数,使在下面的例子中node_idunordered_set的关键?

#include <iostream>
#include <unordered_set>

using namespace std;

// How can I define a hash function that makes 'node' use 'node_id' as key?    
struct node
{
    string node_id;
    double value;
    node(string id, double val) : node_id(id), value(val) {}
};

int main()
{
    unordered_set<node> set;
    set.insert(node("1001", 100));
    if(set.find("1001") != set.end()) cout << "1001 found" << endl;
}
c++ unordered-set hash-function
3个回答
6
投票

你可以尝试使用下面的散列函数对象(这是很基本的,所以你可能要提高,以避免过多的冲突)。

struct node_hash {
    std::size_t operator()(const node& _node) const {
        return std::hash<std::string>()(_node.node_id);
    }
}
// ...
std::unordered_set<node, node_hash> node_set;

然而,作为一个评论所指出的,你可能会在这里下车用std::unordered_map<std::string, double>更好。


2
投票

您需要实现一个自定义的哈希函数(我建议使用Boost库的函数)来做到这一点。 C ++允许你保存的指针使用unordered_set一个类的对象。在大多数情况下,是应该做的伎俩。


2
投票

我同意sjrowlinson,对于您的具体使用情况的std::unordered_map<std::string, double>可能是更好的选择。但是,如果你想坚持到unordered_set由于某些原因,那么你也可以使用一个lambda expression而不是定义一个散列函数。但你也必须提供一个比较函数(equal)使你的代码工作。如果你希望两个node实例相等如果他们有相同的node_id,那么你可以使用下面的代码:

auto hash = [](const node& n){ return std::hash<std::string>()(n.node_id); };
auto equal = [](const node& n1, const node& n2){ return n1.node_id == n2.node_id; };
std::unordered_set<node, decltype(hash), decltype(equal)> set(8, hash, equal);

但是,如果你想使用std::unordered_set::find(),那么你就不能简单地提供一个字符串(例如"1001"),以该功能,因为它需要一个node对象作为参数。下面的代码(这将创建的临时对象)的伎俩,虽然:

set.insert(node("1001", 100));
if (set.find(node("1001", 0)) != set.end())
    std::cout << "1001 found" << std::endl;

请注意,输出1001 found被印刷,虽然插入valuenode是从赋予value功能(100和0,分别地)的nodefind()不同。这是因为对平等检查时,比较功能equal只考虑node_id

Code on Ideone

© www.soinside.com 2019 - 2024. All rights reserved.