1

I have a need to use std::pair<QColor, char> as a key of unordered_map. As for the pair, I know that there is boost functionality that can be used, but what about the color? Is it enough to just provide the hash template in the std namespace? If so, what would be the best attribute of the color to base the hash on to maximize the performance and minimize collisions? My first thought was about simple name(). If so

namespace std {
    struct hash<Key>
    {
        std::size_t operator()(const Key& k) const {
            return std::hash<std::string>()(k.name());
    }
}

The code above is taken from C++ unordered_map using a custom class type as the key.

sauce
  • 123
  • 6

1 Answers1

0

What you propose will probably work (although you would have to convert the color name from QString to std::string), I would use the RGBA value of the color directly. It is a bit cheaper than having to go through the QString to std::string construction and hash calculation:

template<>
struct std::hash<QColor>
{
  std::size_t operator()(const QColor& c) const noexcept
  {
    return std::hash<unsigned int>{}(c.rgba());
  }
};

According to Qt's documentation, QRgb returned by QColor::rgba() is some type equivalent to unsigned int.

Ton van den Heuvel
  • 10,157
  • 6
  • 43
  • 82
  • one question: where is it better to define this extension of std::hash? in a separate header and then just include it or just some source file? – sauce Nov 30 '21 at 22:28
  • 1
    It depends, in case you only need this hashing functionality in one `.cpp` file (translation unit), you can just put it in that one, otherwise, put it in a header. – Ton van den Heuvel Dec 01 '21 at 15:17