将 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_TYPEDEF
的boost 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>
专业。
我正在使用 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_TYPEDEF
的boost 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>
专业。