如何为自定义类型扩展std :: tr1 :: hash?

时间:2009-03-15 15:14:25

标签: c++ tr1

如何让STL实现获取自定义类型?在MSVC上,有一个类std::tr1::hash,我可以通过使用

来部分专门化
namespace std 
{
    namespace tr1 
    { 
        template <> 
        struct hash<MyType> 
        { ... };
    } 
}

但这是推荐的方式吗?此外,这是否也适用于GCC的实施?对于boost::hash,它足以提供一个自由函数size_t hash_value (const MyType&),是否有类似于TR1实现的东西?

4 个答案:

答案 0 :(得分:21)

我试图找出使用无序关联容器执行此操作的确切语法(也正如OP所要求的那样使用GCC)并点击此问题。

不幸的是,它没有达到我想要的细节水平。通过查看gcc标头如何实现标准哈希函数,我得到了它的工作。 鉴于网上缺乏示例(至少在撰写本文时),我认为这将是发布我自己的例子(我可以确认与GCC合作)的好地方:


namespace std { namespace tr1
{
   template <>
   struct hash<MyType> : public unary_function<MyType, size_t>
   {
       size_t operator()(const MyType& v) const
       {
           return /* my hash algorithm */;
       }
   };
}}

(注意 这里有两个命名空间 - 这只是我对折叠嵌套命名空间的约定)

答案 1 :(得分:4)

是的,这对GCC也有效。我在一个更大的项目中使用它,它没有问题。您还可以为TR1容器提供自己的自定义哈希类,但是指定std :: tr1 :: hash&lt;&gt;是默认的散列类。专门用于自定义类型似乎是扩展标准散列功能的自然方式。

答案 2 :(得分:3)

由于您没有添加std库名称空间,而只是提供专业化,因此完全没问题。

如果你想提供更通用的哈希方法(例如一般的元组哈希),那么看看Boost Fusion。 Here is a simple example,适用于大多数情况(可能除元组元组外)

答案 3 :(得分:0)

以下代码段显示了如何将std::tr1::unordered_map专门化为映射 boost::const_string<char>void*类似于std::string的散列方式。

#include <boost/const_string/const_string.hpp>    
typedef class boost::const_string<char> csc;

namespace std
{
namespace tr1
{
template <>
struct hash<csc> {
public:
    size_t operator()(const csc & x) const {
        return std::_Hash_impl::hash(x.data(), x.size());
    }
};
}
}

typedef std::tr1::unordered_map<csc, void*> Map;
typedef Map::value_type Dual; ///< Element Type.