22

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

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

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

4

4 回答 4

21

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

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

于 2009-04-05T14:27:55.167 回答
4

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

于 2009-03-15T15:24:17.347 回答
3

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

如果您想提供更通用的散列方法(例如一般的元组散列),请查看 Boost Fusion。这是一个简单的例子,它适用于大多数情况(可能元组的元组除外)

于 2009-03-15T15:44:36.923 回答
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.
于 2011-05-05T14:59:24.907 回答