我可以使用成员变量作为 hash_set/hash_map 的键吗?
我有一个这样的类:
class Foo
{
long long Id;
string x;
string y;
// other member variables and functions
};
我想将其存储在 hash_set
(或 hash_map
)中,但使用 Id 成员变量作为插入和搜索的键。我不知道我该怎么做。我想到了以下方法,但没有一个是真正好的:
1)我可以编写一个自定义哈希函数,该函数将使用 Id 对对象进行哈希处理,但随后我无法使用 find()
hash_set 上的方法通过 Id (long long
) 查找项目,因为它需要传入 Foo
对象。
2) 我可以复制 Id 并创建一个 hash_map
而不是 hash_set
但我有 1 亿个这些对象的实例所以我不想重复 Id 字段。
3)我可以将 Id 字段移到 Foo
之外,然后执行 hash_map
,但这会有点混乱,因为 Id 在内部使用类,最好将其保留在 Foo
中。
有什么想法吗?我正在寻找的是一种存储 Foo
对象的方法,但能够使用 long long
在 hash_set
中搜索它们(通过ID)。
谢谢!
I have a class like this:
class Foo
{
long long Id;
string x;
string y;
// other member variables and functions
};
I would like to store this in a hash_set
(or hash_map
), but use the Id member variable as the key for inserting and searching. I'm not sure how I can do this. I thought of the following ways, but none of them are really good:
1) I can write a custom hash function that will hash the object using the Id, but then I can't use the find()
method on hash_set
to lookup the item by Id (long long
) since it will require a Foo
object to be passed-in.
2) I can duplicate the Id and create ahash_map<long long, Foo>
instead of a hash_set<long long, Foo>
but I have 100 million instances of these objects so I'd rather not duplicate the Id field.
3) I can move the Id field outside of Foo
and then do hash_map<long long, Foo>
, but it would be kind of messy since the Id is used internally by the class and it would be better to keep it with Foo
.
Any ideas? What I'm looking for is a way to store Foo
objects but be able to search for them in the hash_set
using a long long
(by Id).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是标准地图和集合容器的常见问题。添加一个构造函数或静态成员来创建一个比较对象,一个只有键成员有效的对象。
This is a common problem with the standard map and set containers. Add a constructor or static member that creates a comparison object, an object with only the key member valid.
选项 2 是您给出的三个选项中最好的选择。如果您愿意,您可以编写一个自定义 hash_set (甚至只是常规 hash_set 的包装器)来提供您想要的内容。在这种情况下,我更喜欢选项 1。您可以轻松添加一个仅接受键值的查找函数,并对其进行调整以正确使用内部查找函数,从而为您带来所有好处。
Option 2 is your best bet among the three you gave. If you're up to it, you could write a custom hash_set (even just a wrapper around the regular one) to provide what you want. In that case, I'd prefer option 1. You could easily add a find function that takes just the key value and adapts it to use the internal find function properly giving you all benefits.
我对此没有太多经验,但 boost::multiindex 默认构建在 boost::hash 之上,并且明确支持仅使用对象中找到的键在哈希中查找对象。
I don't have much experience with it, but boost::multiindex is built on top of boost::hash by default, and has explicit support for looking up an object in a hash using only a key found in the object.
如果您没有找到 hash_set/hash_map 容器的实际解决方案,您可能需要考虑使用 uthash哈希表实现,直接支持您的用例。虽然它是 C 语言,并且基于宏,但它是现有的最流行的哈希表实现之一。
If you don't find an actual solution for the hash_set/hash_map containers, you may want to consider using the uthash hash table implementation, which supports your use case directly. It's C though and it's based on macros but it's one of the most popular hash table implementations that exist.
这可能不是一个特别优雅的解决方案,但它有效:为排序对象的类定义一个
operator <
(以及operator ==
,正如 CashCow 建议的那样)基于Id
字段,然后当您想要进行查找
时,传入一个包含您要查找的Id
的虚拟对象。This may not be a particularly elegant solution, but it works: define an
operator <
(andoperator ==
as well, as CashCow suggested) for your class that orders objects based on theId
field, then when you want to do afind
, pass in a dummy object that contains theId
you're looking for.