Вопрос по c++, tr1 –  хэшируется

22

могу позволить реализации STL подобрать мои пользовательские типы? На MSVC есть классstd::tr1::hash, который я могу частично специализировать, используя

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

но это рекомендуемый способ? Кроме того, это работает с реализацией GCC? Заboost::hashдостаточно предоставить бесплатную функциюsize_t hash_value (const MyType&)Есть ли что-то подобное для реализации TR1?

Есть ли способ расширить std :: hash для пользовательских типов с помощью частных конструкторов копирования? Кроме того, есть ли способ расширить его с помощью оператора (), который принимает const ref вместо val? Ben Collins
В чем проблема со специализацией шаблона? Вы не берете копию своего объекта (вы передаете его по ссылкам), поэтому нет проблем - и оператор () принимает константный ref или значение, что вы хотите. Посмотрите на ответ Фила Нэша, который принимает объект как const ref. Anteru

Ваш Ответ

4   ответа
21

оциативными контейнерами (также используя 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 */;
       }
   };
}}

(обратите внимание, тамнаходятся здесь два пространства имен - это просто мое соглашение для свертывания вложенных пространств имен)

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.
4

это также будет работать для GCC. Я использую его в большем проекте, и он работает без проблем. Вы также можете предоставить свой собственный класс хеширования для контейнеров TR1, но указано, что std :: tr1 :: hash <> является классом хеширования по умолчанию. Специализировать его для пользовательских типов кажется естественным способом расширить стандартную функциональность хеширования.

3

std Пространство имен библиотеки, но только с предоставлением специализаций, тогда это совершенно нормально.

Если вы хотите обеспечить более общий подход к хешированию (например, хеш для кортежей в целом), взгляните на Boost Fusion.Вот простой пример, который будет работать в большинстве случаев (возможно, за исключением кортежей кортежей)

Похожие вопросы