【问题标题】:C++11 Hash function for any enum type任何枚举类型的 C++11 哈希函数
【发布时间】:2012-03-10 12:08:37
【问题描述】:

我正在为我的对象编写一个哈希函数。感谢Generic Hash function for all STL-containers,我已经可以散列容器并组合散列。但我的课程也有枚举。当然,我可以为每个枚举创建一个哈希函数,但这似乎不是一个好主意。是否可以为std::hash 创建一些通用规范,以便将其应用于每个枚举?类似的东西,使用std::enable_ifstd::is_enum

namespace std {
  template <class E>
  class hash<typename std::enable_if<std::is_enum<E>::value, E>::type> {
  public:
    size_t operator()( const E& e ) const {
      return std::hash<std::underlying_type<E>::type>()( e );
    }
  };
};

PS。此代码无法编译

error: template parameters not used in partial specialization:
error:         ‘E’

【问题讨论】:

    标签: c++ templates enums c++11 hash-function


    【解决方案1】:

    您的E 参数无法推导出来,因为编译器无法知道您的enable_if&lt;...&gt;::type 最终再次表示E(事实上,它的一些专业化设计不这样做!) .对于E,它被称为“非推断上下文”。

    如果hash 只有一个参数,就没有办法(据我所知)SFINAE 排除您的部分专业化。

    【讨论】:

      【解决方案2】:

      如果您愿意使用宏,您可以在枚举声明旁边转储正确的 std::hash 特化。

      否则,我发现轻松散列枚举值的唯一方法是概括散列类型:

      struct enum_hash
      {
          template <typename T>
          inline
          typename std::enable_if<std::is_enum<T>::value, std::size_t>::type
          operator ()(T const value) const
          {
              return static_cast<std::size_t>(value);
          }
      };
      

      并以这种方式使用它:

      enum class E { a, b, c };
      std::unordered_map<E, std:string, enum_hash> map;
      map[E::a] = "a";
      

      【讨论】:

        【解决方案3】:

        标准禁止您尝试做的事情。

        [命名空间.std]

        如果 C++ 程序添加声明或 对命名空间 std 或命名空间 std 内的命名空间的定义 除非另有说明。

        程序可以为任何 标准库模板到命名空间 std 仅当声明 取决于用户定义的类型,并且专业化满足 原始模板的标准库要求,而不是 明确禁止。

        因此,您当然可以在这些答案中追求一些想法,但不能将其称为 std::hash。定义自己的“enum_hash”模板似乎是个好主意。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-10
          • 1970-01-01
          相关资源
          最近更新 更多