将 Boost strong typedef 与 unordered_map 一起使用

Using Boost strong typedef with unordered_map

我正在使用 Boost strong typedef 来强类型 uint64_t:

BOOST_STRONG_TYPEDEF(uint64_t, MyInt)

和一个 std::unordered_map 使用这个:

std::unordered_map<MyInt, int> umap;

不幸的是,我遇到了很多编译器错误(无法粘贴到这里,因为它们在另一台机器上):

error: static assertion failed: hash function must be invocable with an argument of key type
.static_assert(__is_invocable<const _H1&, const _Key&>)

error: use of deleted function 'std::__detail::_Hashtable_ebo_helper

_Hashtable() = default;

(+ 很多我打不出来)

使用 Boost 强类型作为键肯定会导致问题,因为如果我删除 unordered_map 我不会收到编译器错误。

从关于BOOST_STRONG_TYPEDEFboost documentation中明确提到,它定义了一个新的类型来包装目标内部类型(它不是一个简单的别名)。

知道,没有定义的 std::hash<MyInt> 可用专业化(std::unordered_map<MyInt, int> 要求),因为 MyInt 现在是不同于 uint64_t 的类型。

您只需要提供一个,它应该会按预期工作。

例如:

namespace std
{
    template <>
    struct hash<MyInt>
    {
        size_t operator()(const MyInt & m) const
        {
            return hash<uint64_t>{}(m);
        }
    };
}

编辑:

正如评论中指出的那样,您也可以直接传递适当的 std::hash<> 特化以从 std::unordered_map<> 实例化中用作第三个模板参数,因为 MyInt 可以隐式转换为 uint64_t(也如 boost 文档中所述)。

它将变成:

std::unordered_map<MyInt, int, std::hash<uint64_t>> umap;

无需再定义自己的 std::hash<MyInt> 专业。