Background: I am comming from the Java world and I am fairly new to C++ or Qt.
In order to play with unordered_map, I have written the following simple program:
#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();
}
Unfortunately, I am running into the folowing error which isn’t inspiring. There is not even a line number.
:-1: error: collect2: ld returned 1 exit status
Any idea of the origin of the problem?
§23.2.5, paragraph 3, says:
Using
vector<float>asKeyand not providing explicit hash and equivalence predicate types means the defaultstd::hash<vector<float>>andstd::equal_to<vector<float>>will be used.The
std::equal_tofor the equivalence relation is fine, because there is an operator==for vectors, and that’s whatstd::equal_touses.There is however, no
std::hash<vector<float>>specialization, and that’s probably what the linker error you didn’t show us says. You need to provide your own hasher for this to work.An easy way of writing such an hasher is to use
boost::hash_range:Then you can use:
Of course, if you need different equality semantics in the map you need to define the hash and equivalence relation appropriately.
1. However, avoid this for hashing unordered containers, as different orders will produce different hashes, and the order in unordered container is not guaranteed.