gpt4 book ai didi

c++ - 如何覆盖类内定义的枚举的 std::hash?

转载 作者:可可西里 更新时间:2023-11-01 16:09:53 28 4
gpt4 key购买 nike

我在一个类中定义了一个枚举类型,我想创建一个由这些对象组成的 unordered_set 作为该类的成员:

#include <unordered_set>

class Foo {
public:
enum Bar {
SOME_VALUE
};

// Error: implicit instantiation of std::hash
std::unordered_set<Bar> getValues() const {
return _values;
}

private:
std::unordered_set<Bar> _values;
};

现在,我知道显而易见的答案是向 unordered_set 添加自定义哈希函数:

std::unordered_set<Bar, BarHasher>

但是,我想知道是否有一种方法可以为 Bar 枚举专门化 std::hash,以便使用 unordered_map 的任何人都可以自动获得散列行为。

这适用于所有其他数据类型,但不适用于枚举 - 因为枚举不能前向声明。

为了让它工作,我必须将 std::hash 的定义放在枚举定义之后,但在第一次使用之前,这意味着我必须将它放在类主体的中间,这是行不通的。

最佳答案

However, what I'm wondering is if there's a way to specialize std::hash for the Bar enum so that anyone who uses unordered_map gets the hashing behavior automatically.

没有奇迹,所以只有在专门化之后,任何人都会使用专门化的 std::hash。由于您不能在另一个类中专门化类并且您的枚举是嵌套的,因此在类中使用 std::hash 会出现问题。正如您指出的那样,枚举不能向前声明。因此,唯一的解决方案(无需创建基类或“取消嵌套”枚举)在类内部使用专门的 std::hash:通过引用聚合/声明并在 std::之后使用外部哈希特化。

#include <iostream>
#include <unordered_set>
#include <memory>

struct A {

enum E {
first, second
};

A();

std::unique_ptr< std::unordered_set<E> > s_; //!< Here is
};

namespace std {

template<>
class hash<A::E> {
public:
std::size_t operator()(A::E const& key) const noexcept {
std::cout << "hash< A::E >::operator()" << std::endl;
return key;
}

};

}

A::A()
: s_(new std::unordered_set<E>)
{ }

int main(void) {
A a;
a.s_->insert(A::first);

std::unordered_set< A::E > s;
s.insert(A::second);
}

打印出来

hash< A::E >::operator()
hash< A::E >::operator()

因此,在类 A 之外,每个人都可以将 A::Estd::hash 一起使用,我们也可以在类内使用将 A::Estd::hash 一起使用。此外,如果您不想通过引用聚合 std::unordered_set,您可以实现自定义散列器仅供内部使用(然后将 std::hash 调用转发给它).

关于c++ - 如何覆盖类内定义的枚举的 std::hash?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32800040/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com