如何在 boost::unordered_map 中使用自定义类型的键?
我现在正在项目中使用 Boost 的哈希映射实现,并且我正在尝试实现键的自定义类型。我有四个无符号整数,我想将它们组合成一个 128 位数据类型以用作密钥。
我创建了一个包含四个元素的 32 位整数数组的结构体,用作我的存储。老实说,我不确定Boost的哈希图是如何工作的,所以我不确定我在这里做什么,但我遵循了Boost文档(http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html) 用于扩展 boost::hash,我创建了一个哈希函数以及一个自定义比较运算符。
我在标头中定义了此自定义类型。这是我的代码:
#ifndef INT128_H_
#define INT128_H_
// Custom 128-bit datatype used to store and compare the results of a weakened hash operation.
struct int128
{
unsigned int storage[4];
/* Assignment operation that takes a 32-bit integer array of four elements.
This makes assignment of values a shorter and less painful operation. */
void operator=(const unsigned int input[4])
{
for(int i = 0; i < 4; i++)
storage[i] = input[i];
}
};
bool operator==(int128 const &o1, int128 const &o2)
{
if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] &&
o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3])
return true;
return false;
}
// Hash function to make int128 work with boost::hash.
std::size_t hash_value(int128 const &input)
{
boost::hash<unsigned long long> hasher;
unsigned long long hashVal = input.storage[0];
for(int i = 1; i < 3; i++)
{
hashVal *= 37;
hashVal += input.storage[1];
}
return hasher(hashVal);
}
#endif
现在,当我在 Boost 的无序映射中实际使用这种类型时,我的代码可以编译,但无法链接。链接器声称我在多个目标文件中多次定义了一个符号。我真的很想让我的 128 位类型与这张地图一起工作。关于我搞砸的事情有什么建议,或者更好的方法吗?
I'm using Boost's implementation of a hash map in a project right now, and I'm trying to implement a custom type for keys. I have four unsigned integers which I'd like to combine into a single 128-bit datatype to use as a key.
I've created a struct with a 32-bit integer array of four elements, which serves as my storage. To be honest, I'm not sure how Boost's hash map works, so I'm not sure what I'm doing here, but I followed the Boost documentation (http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html) for extending boost::hash, and I created a hash function, as well as a custom comparison operator.
I have this custom type defined in a header. This is my code:
#ifndef INT128_H_
#define INT128_H_
// Custom 128-bit datatype used to store and compare the results of a weakened hash operation.
struct int128
{
unsigned int storage[4];
/* Assignment operation that takes a 32-bit integer array of four elements.
This makes assignment of values a shorter and less painful operation. */
void operator=(const unsigned int input[4])
{
for(int i = 0; i < 4; i++)
storage[i] = input[i];
}
};
bool operator==(int128 const &o1, int128 const &o2)
{
if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] &&
o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3])
return true;
return false;
}
// Hash function to make int128 work with boost::hash.
std::size_t hash_value(int128 const &input)
{
boost::hash<unsigned long long> hasher;
unsigned long long hashVal = input.storage[0];
for(int i = 1; i < 3; i++)
{
hashVal *= 37;
hashVal += input.storage[1];
}
return hasher(hashVal);
}
#endif
Now when I actually use this type in Boost's unordered map, my code compiles, but fails to link. The linker claims that I have a symbol defined multiple times in several object files. I'd really like to get my 128-bit type working with this map. Any tips on what I'm screwing up, or a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无序映射的参与几乎是您遇到的问题的偶然。真正的问题是您在包含上述标头的每个文件中定义
hash_value
和operator==
。您可以通过以下任一方法解决此问题:
如果您执行后者(这就是您通常想要的),您将把这些函数的定义移动到
.cpp 中
文件(或任何用于 C++ 源文件的扩展名)。然后,您将编译该文件,并将生成的对象与使用 int128 类型的其他代码链接。编辑:您仍然可以使比较更清晰,例如:
The involvement of unordered-map is almost incidental to the problem you're encountering. The real problem is that you're defining
hash_value
andoperator==
in every file that includes the header above.You can cure this by either:
If you do the latter (and it's what you'll usually want) you'll move the definitions of those functions into a
.cpp
file (or whatever extension you use for C++ source files). You'll then compile that file, and link the resulting object with your other code that uses the int128 type.Edit: You can still make your comparison cleaner, something like:
将您的函数声明为
内联
declare your functions as
inline