I'm trying to use the following custom unordered_map
using pair = std::pair<char, QColor>;
using cache = std::unordered_map<pair, QPixmap, boost::hash<pair>>;
cache _cache;
I defined the hash function for QColor as follows
template<>
struct std::hash<QColor>
{
std::size_t operator()(const QColor &color) const noexcept
{
return std::hash<QRgb>{}(color.rgb());
}
};
but no matter where I place it, whether it is a header or source file, I get a verbose compile time error from boost
C:\boost_1_77_0\boost\container_hash\extensions.hpp:305: error: C2665: 'boost::hash_value': none of the 3 overloads could convert all the argument types
C:\boost_1_77_0\boost/container_hash/hash.hpp(550): note: could be 'size_t boost::hash_value(const std::error_condition &)'
C:\boost_1_77_0\boost/container_hash/hash.hpp(543): note: or 'size_t boost::hash_value(const std::error_code &)'
C:\boost_1_77_0\boost/container_hash/hash.hpp(536): note: or 'size_t boost::hash_value(std::type_index)'
C:\boost_1_77_0\boost/container_hash/extensions.hpp(305): note: while trying to match the argument list '(const T)'
It is the last message of all. I think that boost's hashing function for pair doesn't see the hash function I defined. Do I need define it in the boost's namespace? And in general, what's the rule for defining the specific versions of templates? Why the rule that the templates must be defined in header files only doesn't apply here?
UPD: The structure of my project is as follows
// foo.h
#include <QtWidgets>
#include <boost/functional/hash.hpp>
#include <unordered_map>
template<>
struct std::hash<QColor>
{
std::size_t operator()(const QColor &color) const noexcept
{
return std::hash<QRgb>{}(color.rgb());
}
};
class Foo
{
private:
using Pair = std::pair<char, QColor>;
const QPixmap &getPixmapForPair(Pair c);
using CharsCache = std::unordered_map<Pair, QPixmap, boost::hash<Pair>>;
CharsCache _cache;
}
// foo.cpp
const QPixmap &Foo::getPixmapForPair(Pair c)
{
auto it = _cache.find(c);
if (it != _cache.end())
return it->second;
}
Very oversimplified, but delivers the general idea.