I have a map inserting multiple values with the same type key C string.
I would expect to have one entry with the specified key.
However, the card appears to take its address into account when uniquely identifying the key.
#include <cassert>
#include <iostream>
#include <string>
#include <unordered_map>
typedef char const* const MyKey;
struct MyMapHash {
public:
size_t operator()(MyKey& key) const {
return std::hash<std::string>{}(std::string(key));
}
};
typedef std::unordered_map<MyKey, int, MyMapHash> MyMap;
int main()
{
std::string key1_s = "same";
std::string key2_s = "same";
MyKey key1 = key1_s.c_str();
MyKey key2 = key2_s.c_str();
assert(key1 != key2);
assert(MyMapHash{}(key1) == MyMapHash{}(key2));
MyMap map;
map.insert({key1, 1});
map.insert({key2, 2});
auto it1 = map.find(key1);
auto it2 = map.find(key2);
assert(it1 != map.end());
assert(it2 != map.end());
int value1 = it1->second;
int value2 = it2->second;
assert(value1 == value2);
assert(map.size() == 1u);
}
The fingerprint in the debugger shows that the card contains two elements immediately after they are inserted.
(gdb) p map
$4 = std::unordered_map with 2 elements = {
[0x7fffffffda20 "same"] = 2,
[0x7fffffffda00 "same"] = 1
}
Why does this happen if a hash function that delegates a value std::hash<std::string>takes into account only its value (this is indicated in the code)?
Also, if this is the intended behavior, how can I use a card with a C string as a key, but with a key value display of 1: 1?
source
share