代码之家  ›  专栏  ›  技术社区  ›  Anteru

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

  •  22
  • Anteru  · 技术社区  · 16 年前

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

    namespace std 
    {
        namespace tr1 
        { 
            template <> 
            struct hash<MyType> 
            { ... };
        } 
    }
    

    但这是推荐的方法吗?此外,这是否也适用于GCC的实现?为了 boost::hash 足够提供一个自由的功能 size_t hash_value (const MyType&) ,TR1实现是否有类似的内容?

    4 回复  |  直到 14 年前
        1
  •  4
  •   sth    16 年前

    是的,这也适用于GCC。我在一个更大的项目中使用它,它毫无问题地工作。您也可以为tr1容器提供自己的自定义散列类,但指定std::tr1::hash<>是默认散列类。将它专门用于自定义类型似乎是扩展标准散列功能的自然方法。

        2
  •  21
  •   philsquared    16 年前

    我试图用无序的关联容器(同样使用gcc,正如op所要求的那样)计算出执行此操作的确切语法,然后点击这个问题。

    不幸的是,它没有达到我想要的细节水平。通过查看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 */;
           }
       };
    }}
    
    

    (通知) 这里有两个名称空间-这只是我折叠嵌套名称空间的约定)

        3
  •  3
  •   Anonymous    16 年前

    因为你没有加入 std 库名称空间,但只提供特殊功能,那么它是完全正常的。

    如果您想提供更通用的散列方法(例如,通常是元组的散列),那么可以看看BoostFusion。 Here is a simple example ,这将适用于大多数情况(可能有元组的元组例外)

        4
  •  0
  •   Nordlöw    14 年前

    下面的代码段显示了如何专门化 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.