我的std::unordered_map中的密钥是 boost::uuids::uuid ,因此128位哈希被认为是唯一的。但是,编译器不知道这一点,因此可以这样说。

error C2338: The C++ Standard doesn't provide a hash for this type.

如何使 map 按原样使用散列键?顺便说一句,std::size_t在我的系统上定义为unsigned int __w64,我认为它仅指64位。

最佳答案

您始终需要提供将键映射到哈希值的函数对象,即使此映射是标识。您可以为std::hash<boost::uuids::uuid>定义一种特殊化,然后让std::unordered_map<K, V>自动选择此一种,也可以使用函数对象类型的附加模板参数来对无序映射进行参数化。除了哈希之外,还需要一个相等操作,但是使用operator==()的默认操作可能是可以的。

就是说,除非您的系统具有内置的128位整数类型,否则哈希值将不接受128位整数。哈希值必须是std::size_t,才能与标准无序容器一起使用。 std::hash<T>特化要求的完整列表在20.8.12 [unord.hash]中列出:

  • std::hash<X>必须是默认可构造的,可复制构造的和可复制分配的。
  • std::hash<X>需要可交换。
  • 它需要为密钥类型提供两种嵌套类型argument_type,为哈希值的类型提供result_type,后者与std::size_t相同。
  • 对于该函数,关系k1 == k2 => h(k1) == h(k2)必须为true,其中h是哈希函数对象。

  • 因此,您需要按照以下方式定义一些内容:
    namespace std {
        template <>
        struct hash<boost::uuids::uuid>
        {
            typedef boost::uuids::uuid argument_type;
            typedef std::size_t        result_type;
            std::size_t operator()(boost::uuid::uuid key) const {
                return transform_to_size_t(key);
            }
        };
    }
    

    其中transform_to_size_t()是您需要提供的实际转换。
    };

    关于c++ - 如何直接将键用作std::unordered_map的哈希?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18548585/

    10-11 22:38
    查看更多