c – 如何覆盖std :: hash为类中定义的枚举?

我有一个在类中定义的枚举类型,我想创建一个无序的这些对象作为类的成员:
#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 :: hash专门化之后使用外部.

#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 :: E与std :: hash以及内部类,我们也使用A :: E与std :: hash.另外,如果您不想通过引用聚合std :: unordered_set,则可以仅实现内部使用的自定义哈希值(然后转发std ::哈希调用).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...