unordered_map 和具有值语义的指针
unordered_map and pointers with value semantics
我定义了一个 Term 类型,它可以通过指针访问但具有值语义;如果两个不同的 Term 对象具有相同的内容,则它们在逻辑上是相等的。我需要将它们用作地图键。
第一次尝试可能是 unordered_map<Term*, int>
,但这本身并没有获得值语义。需要自定义散列和相等比较函数。 (出于多种原因,我想全局定义这些,而不是在每种情况下都必须将它们作为额外的模板参数提供。)
自定义哈希函数可以像iirc那样定义
namespace std {
template <>
struct hash<Term*> ...
但是unordered_map
比较键和==
,你不能在内置类型上定义自定义运算符,所有指针都是内置类型。
我可以定义一个只包含 Term*
的包装器 class 并将其用作键。有没有更简单的解决方案?
如果你看一下unordered_map
的定义:
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
你可以看到你可以定义一个自定义运算符作为第四个模板参数进行比较。在您的情况下,您只会在 unordered_map
创建时提供一次,而没有 "having to supply them as extra template arguments in every case":
struct custom_operator {
bool operator()(Term* lhs, Term* rhs) const { ... }
};
然后将其用作:
std::unordered_map< Term*, int
, std::hash<Term*>
, custom_operator> map;
无论如何,我强烈建议不要使用指针作为哈希映射的键。如果逻辑上你希望 Term
成为关键,你应该 std::unordered_map<Term, int>
.
我定义了一个 Term 类型,它可以通过指针访问但具有值语义;如果两个不同的 Term 对象具有相同的内容,则它们在逻辑上是相等的。我需要将它们用作地图键。
第一次尝试可能是 unordered_map<Term*, int>
,但这本身并没有获得值语义。需要自定义散列和相等比较函数。 (出于多种原因,我想全局定义这些,而不是在每种情况下都必须将它们作为额外的模板参数提供。)
自定义哈希函数可以像iirc那样定义
namespace std {
template <>
struct hash<Term*> ...
但是unordered_map
比较键和==
,你不能在内置类型上定义自定义运算符,所有指针都是内置类型。
我可以定义一个只包含 Term*
的包装器 class 并将其用作键。有没有更简单的解决方案?
如果你看一下unordered_map
的定义:
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
你可以看到你可以定义一个自定义运算符作为第四个模板参数进行比较。在您的情况下,您只会在 unordered_map
创建时提供一次,而没有 "having to supply them as extra template arguments in every case":
struct custom_operator {
bool operator()(Term* lhs, Term* rhs) const { ... }
};
然后将其用作:
std::unordered_map< Term*, int
, std::hash<Term*>
, custom_operator> map;
无论如何,我强烈建议不要使用指针作为哈希映射的键。如果逻辑上你希望 Term
成为关键,你应该 std::unordered_map<Term, int>
.