与载体作为密钥使用时C ++ unordered_map失败(C++ unordered_map f

2019-06-24 03:02发布

背景:我从Java世界,并正在添加我是相当新的C ++或Qt的。

为了与unordered_map玩,我已经写了下面的程序:

#include <QtCore/QCoreApplication>
#include <QtCore>
#include <iostream>
#include <stdio.h>
#include <string>
#include <unordered_map>

using std::string;
using std::cout;
using std::endl;
typedef std::vector<float> floatVector;

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    floatVector c(10);
    floatVector b(10);

    for (int i = 0; i < 10; i++) {
        c[i] = i + 1;
        b[i] = i * 2;
    }

    std::unordered_map<floatVector, int> map;

    map[b] = 135;
    map[c] = 40;
    map[c] = 32;

    std::cout << "b -> " << map[b] << std::endl;
    std::cout << "c -> " << map[c] << std::endl;
    std::cout << "Contains? -> " << map.size() << std::endl;

    return a.exec();
}

不幸的是,我遇到了未激发如下因素的错误。 甚至没有行号。

:-1:错误:collect2:劳工处返回1个退出状态

任何想法问题的由来吗?

提前致谢。

Answer 1:

§23.2.5,第3款,他说:

每个无序关联容器通过参数化Key ,由函数对象类型Hash满足哈希要求(17.6.3.4)和充当类型的参数值的散列函数Key ,并且由二进制谓词Pred诱导上的等价关系类型的值Key

使用vector<float>作为Key而不是提供明确的散列和等价谓词类型装置的默认std::hash<vector<float>>std::equal_to<vector<float>>将被使用。

std::equal_to的等价关系是好的,因为有运营商==为载体,这就是std::equal_to使用。

然而有,没有std::hash<vector<float>>专业化,这可能是什么链接错误你没有告诉我们说。 您需要提供自己的散列器这个工作。

写这样的散列器的一个简单的方法是使用boost::hash_range

template <typename Container> // we can make this generic for any container [1]
struct container_hash {
    std::size_t operator()(Container const& c) const {
        return boost::hash_range(c.begin(), c.end());
    }
};

然后你可以使用:

std::unordered_map<floatVector, int, container_hash<floaVector>> map;

当然,如果你需要在地图上的不同语义平等,你需要适当地定义哈希和等价关系。


然而,避免这种对散列无序容器,不同的次序会产生不同的散列,并且在无序容器的顺序不被保证。



Answer 2:

我发现R.费尔南德斯Martinho的回答不适合,因为大多数你必须处理所提供的IDE和不能使用外部库,如时代竞争力的编程boost 。 您可以使用下面的方法,如果你想做出最好的STL的。

如上文所述,您只需要编写一个哈希函数。 它应该专注的那种存储在您的矢量数据。 下面散列函数假定int类型的数据:

struct VectorHasher {
    int operator()(const vector<int> &V) const {
        int hash=0;
        for(int i=0;i<V.size();i++) {
            hash+=V[i]; // Can be anything
        }
        return hash;
    }
};

请注意,您可以使用任何一种操作来生成散列。 你只需要,使冲突最小化是创造性的。 例如, hash^=V[i]hash|=V[i]hash+=V[i]*V[i]或甚至hash+=(V[i]<<i)*(V[i]<<i)*(V[i]<<i)都是有效的,直到当然,你的哈希值不溢出。

最后使用这个散列函数与unordered_map ,如下初始化:

unordered_map<vector<int>,bool,VectorHasher> hashMap;


文章来源: C++ unordered_map fail when used with a vector as key