7

我试图为我自己的类型专门化哈希,一个模板键。

我是基于cppreference

我收到编译错误“C++ 标准不提供这种类型的哈希”。我想我只是做错了。编译器甚至可以支持这种模板吗?

namespace std {
    template<typename SType, typename AType, typename PType>
    struct MyKey {
        const SType from;
        const AType consume;
        const PType pop;
    };

    template<typename SType, typename AType, typename PType>
    struct hash<MyKey<SType, AType, PType>> {
        size_t operator ()(MyKey const &key) {
            std::hash<SType>()(key.from);
            std::hash<AType>()(key.consume);
            std::hash<PType>()(key.pop);
        }
    };
}
4

1 回答 1

4

您的代码存在一些问题:

不允许将新的定义或声明放入std命名空间;只允许特殊化(例如std::hash)。所以你的MyKey模板应该移出std命名空间。

你的operator()签名不正确。MyKey没有命名类型,您需要明确地将其参数化。此外,操作员应标记为const

std::hash专业化应提供成员类型argument_typeresult_type.

如果作为等传递的类型没有现有的特化SType,您需要自己提供它们。

您没有从散列函数返回任何内容,只是计算其他类型的散列并将它们的返回值丢弃。

将为具有自己std::hash专业化的类型编译的实现:

//moved out of std
template<typename SType, typename AType, typename PType>
struct MyKey {
    const SType from;
    const AType consume;
    const PType pop;
};

namespace std {
    template<typename SType, typename AType, typename PType>
    struct hash<MyKey<SType, AType, PType>>{
        //member types
        using argument_type = MyKey<SType,AType,PType>;
        //arguments specified         ^     ^     ^
        using result_type = std::size_t;

        result_type operator ()(argument_type const& key) const {
        //marked const                                      ^
            //these will fail if SType and friends don't have a std::hash specialization
            result_type s_hash = std::hash<SType>()(key.from);
            result_type a_hash = std::hash<AType>()(key.consume);
            result_type p_hash = std::hash<PType>()(key.pop);

            //in your actual code, you'll want to compute the return type from the above
            return p_hash;
        }
    };
}
于 2015-04-27T10:43:32.840 回答