I am wondering if it is possible to have a std::unordered_map use a fixed size array as a key. For example, here is a simple cache that holds strings as the value but needs a uint8_t[] as the key:
using UserKeyV1 = uint8_t[16];
using UserKeyV2 = uint8_t[32];
template <typename T>
class StringCache
{
public:
bool addString(const T &userKey, const std::string &value)
{
auto [it, result] = m_cache.try_emplace(userKey, value);
// ^^^^^^^ this line won't compile: array initializer must be an initializer list or string literal
}
private:
struct EqualToFn {
bool operator()(const T &left, const T &right) const {
return std::memcmp(&left[0],
&right[0],
sizeof(T)) == 0;
}
};
struct HashFn {
size_t operator()(const T &k) const {
return std::_Hash_impl::hash(k);
}
};
std::unordered_map<T, std::string, HashFn, EqualToFn> cache_;
}
And in use would be something like:
StringCache<UserKey1> cache1;
uint8_t uniqueKey[16]; // this key was provided by 3rd party lib
cache1.addString(uniqueKey, strUsername)
This won't compile due to the error listed above but I'm not sure why. I created the custom hasher and equality functions for the array so that it knew how to handle such a key. I could probably solve this with std::array and copy the key to it first but wanted to avoid that if possible as it would involve a copy and this code will be potentially called 1000s of times a second.
Is what I am trying to achieve possible or do I just use std::array as a key?