【发布时间】:2022-01-07 23:01:29
【问题描述】:
我正在尝试使用以下自定义unordered_map
using pair = std::pair<char, QColor>;
using cache = std::unordered_map<pair, QPixmap, boost::hash<pair>>;
cache _cache;
我为 QColor 定义了如下的哈希函数
template<>
struct std::hash<QColor>
{
std::size_t operator()(const QColor &color) const noexcept
{
return std::hash<QRgb>{}(color.rgb());
}
};
但无论我把它放在哪里,无论是头文件还是源文件,我都会从 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)'
这是最后一条消息。我认为 boost 的 pair 散列函数看不到我定义的散列函数。我需要在 boost 的命名空间中定义它吗?一般来说,定义特定模板版本的规则是什么?为什么模板只能在头文件中定义的规则在这里不适用?
UPD:我的项目结构如下
// 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;
}
非常简单,但传达了总体思路。
【问题讨论】:
-
你能试试this吗?我没有可用的 MSVC + Qt + boost,所以我无法自己验证它,但是当模拟 Qt 类型时,它在 MSVC 中对我有用。如果我删除模拟它在
g++和clang++中工作正常@ -
@TedLyngmo 奇怪,但它确实适用于单个源文件中的模拟和真实 Qt 类型 - 您提供的那个。但是当涉及到结构更复杂的项目时 - 我收到了问题中的错误。我会用我的项目结构解释来更新我的问题。