如何在boost :: unordered_map中为键使用自定义类型?

时间:2009-12-01 23:19:42

标签: c++ boost hashmap unordered-map int128

我正在使用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位类型使用这张地图。关于我搞砸了什么的提示,还是更好的方法呢?

2 个答案:

答案 0 :(得分:3)

无序地图的参与几乎是您遇到的问题的偶然事件。真正的问题是,您要在包含上述标题的每个文件中定义hash_valueoperator==

您可以通过以下方式解决此问题:

  1. 将这两者定义为内联函数
  2. 只是在标题中声明它们
  3. 如果您执行后者(并且这是您通常想要的),您将把这些函数的定义移动到.cpp文件(或者您用于C ++源文件的任何扩展名)。然后,您将编译该文件,并将生成的对象与使用int128类型的其他代码链接。

    编辑:您仍然可以使比较更清晰,例如:

    bool operator==(int128 const &o1, int128 const &o2)
    {
        return o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
               o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]);
    }
    

答案 1 :(得分:1)

  

链接器声称我有一个符号   多次定义多次   目标文件。

将您的职能声明为inline