хэшируется

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

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

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

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

Ответы на вопрос(4)

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

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

как специализироваться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.
Решение Вопроса

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

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

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

Ваш ответ на вопрос