2013-12-15 1 views
25

У меня есть следующий класс с unordered_map члена и хэш-функцию, определенную для pair<int,int>ошибка для хэш-функции пары целых чисел

class abc 
{public : 
    unordered_map < pair<int,int> , int > rules ; 
    unsigned nodes; 
    unsigned packet ;  
}; 

namespace std { 
template <> 
    class hash < std::pair< int,int> >{ 
    public : 
     size_t operator()(const pair< int, int> &x) const 
     { 
      size_t h = std::hash<int>()(x.first)^std::hash<int>()(x.second); 
      return h ; 
     } 
    }; 
} 

Но я получаю следующие ошибки:

error: invalid use of incomplete type ‘struct std::hash<std::pair<int, int> > 

error: declaration of ‘struct std::hash<std::pair<int, int> > 

error: type ‘std::__detail::_Hashtable_ebo_helper<1, std::hash<std::pair<int, int> >, true>’ is not a direct base of ‘std::__detail::_Hash_code_base<std::pair<int, int>, std::pair<const std::pair<int, int>, int>, std::__detail::_Select1st, std::hash<std::pair<int, int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>’ 
+1

Вы должны направить declate 'template класс hash;' – Rapptz

+1

@Rapptz: Недопустимое объявление вперед. OP должен определить специализацию перед классом abc. –

+0

@ JesseGood Да, я вижу это сейчас. – Rapptz

ответ

34

К сожалению, эта программа имеет неопределенное поведение. C++ 11 §17.6.4.2.1:

Программа может добавить специализации шаблона для любых стандартных библиотеки шаблонов для патезраса только если декларация зависит от определяемого пользователя типа и специализация соответствует стандартной библиотеке требования к оригинальному шаблону и явно не запрещены.

hash<pair<int,int>> зависит только от примитивных и стандартных типов библиотек. Это легко обойти, определив свой хэш-класс вне пространства имен std, и используя этот хэш явно в вашей карте декларации:

struct pairhash { 
public: 
    template <typename T, typename U> 
    std::size_t operator()(const std::pair<T, U> &x) const 
    { 
    return std::hash<T>()(x.first)^std::hash<U>()(x.second); 
    } 
}; 

class abc { 
    std::unordered_map<std::pair<int,int>, int, pairhash> rules; 
}; 

EDIT: Я использовал XOR объединить хэш членов пары здесь, потому что я ленив, но для серьезного использования xor is a fairly crappy hash combining function.

+0

Ах, ладно, забыл об этом. –

+5

(тот же комментарий, который я сделал для Джесси) 'std :: hash () (x.first)^std :: hash () (x.second);' - это впечатляюще склонный к столкновению способ хэш-пары ', так как каждая пара с двумя одинаковыми значениями хешируется до 0, а каждая пара {a, b} хешируется так же, как {b, a}. Для смутно требовательного использования гораздо лучше найти функцию «hash_combine» и использовать ее. –

+9

Подождите, так что stl не реализует 'std :: hash' для' std :: pair', но также не позволяет вам реализовать его самостоятельно? Зачем? – Claudiu

 Смежные вопросы

  • Нет связанных вопросов^_^