【问题标题】:How to extend std::tr1::hash for custom types?如何为自定义类型扩展 std::tr1::hash?
【发布时间】:2010-10-13 11:24:00
【问题描述】:

如何让 STL 实现选择我的自定义类型?在 MSVC 上,有一个类 std::tr1::hash,我可以通过使用来部分专门化它

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

但这是推荐的方式吗?此外,这也适用于 GCC 的实现吗?对于boost::hash,提供一个免费的函数size_t hash_value (const MyType&amp;)就够了,TR1的实现有没有类似的东西?

【问题讨论】:

  • 有没有办法使用私有复制构造函数为用户定义的类型扩展 std::hash?另外,有没有办法用一个接受 const ref 而不是 val 的 operator() 来扩展它?
  • 模板专业化有什么问题?你不需要复制你的对象(你通过引用传递它),所以没问题 - 并且 operator() 需要一个 const ref 或值,无论你想要什么。查看 Phil Nash 的答案,它将对象作为 const ref。

标签: c++ tr1


【解决方案1】:

我试图找出使用无序关联容器执行此操作的确切语法(也使用 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 */;
       }
   };
}}

(注意这里两个命名空间——这只是我折叠嵌套命名空间的惯例)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      由于您没有添加到 std 库命名空间,而只是提供专业化,所以完全可以。

      如果您想提供更通用的散列方法(例如一般元组的散列),请查看 Boost Fusion。 Here is a simple example,适用于大多数情况(可能元组的元组除外)

      【讨论】:

        【解决方案4】:

        以下代码 sn -p 显示如何将std::tr1::unordered_map 专门化为映射 boost::const_string&lt;char&gt;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.
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-03
          • 1970-01-01
          • 1970-01-01
          • 2014-08-13
          • 1970-01-01
          • 2015-12-24
          • 1970-01-01
          • 2014-01-08
          相关资源
          最近更新 更多