Неупорядоченный набор пар, ошибка компиляции

Я пытаюсь создать неупорядоченный набор пар

До сих пор я:

typedef std::pair<int, int> Move;
typedef std::unordered_set<Move> Set;

И я буду создавать набор движений в будущем, пока я просто:

Set* King::possibleMoves() 
{
  Set hello;    <-------- THINK ERROR OCCURS HERE
  return &hello;
}

Но я продолжаю получать эти 3 ошибки:

`/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/type_traits:770:38: error: 
  implicit instantiation of undefined template 'std::__1::hash<std::__1::pair<int, int>
  >'
: public integral_constant<bool, __is_empty(_Tp)> {};
                                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1951:40: note: 
  in instantiation of template class
  'std::__1::is_empty<std::__1::hash<std::__1::pair<int, int> > >' requested here
                            bool = is_empty<_T2>::value
                                   ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1973:44: note: 
  in instantiation of default argument for '__libcpp_compressed_pair_switch<unsigned
  long, std::__1::hash<std::__1::pair<int, int> >, false, false>' required here
template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:2357:15: note: 
  in instantiation of default argument for '__libcpp_compressed_pair_imp<unsigned long,
  std::__1::hash<std::__1::pair<int, int> > >' required here
: private __libcpp_compressed_pair_imp<_T1, _T2>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__hash_table:527:55: note: 
  in instantiation of template class 'std::__1::__compressed_pair<unsigned long,
  std::__1::hash<std::__1::pair<int, int> > >' requested here
__compressed_pair<size_type, hasher>              __p2_;
                                                  ^
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/unordered_set:330:13: note: 
  in instantiation of template class 'std::__1::__hash_table<std::__1::pair<int, int>,
  std::__1::hash<std::__1::pair<int, int> >, std::__1::equal_to<std::__1::pair<int, int>
  >, std::__1::allocator<std::__1::pair<int, int> > >' requested here
__table __table_;
        ^
King.cpp:9:7: note: in instantiation of template class
  'std::__1::unordered_set<std::__1::pair<int, int>, std::__1::hash<std::__1::pair<int,
  int> >, std::__1::equal_to<std::__1::pair<int, int> >,
  std::__1::allocator<std::__1::pair<int, int> > >' requested here
 Set hello;
  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:3081:29: note: 
      template is declared here
template <class _Tp> struct hash;
                        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1951:55: error: 
  no member named 'value' in 'std::__1::is_empty<std::__1::hash<std::__1::pair<int, int>
  > >'
                            bool = is_empty<_T2>::value
                                   ~~~~~~~~~~~~~~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1973:44: note: 
  in instantiation of default argument for '__libcpp_compressed_pair_switch<unsigned
  long, std::__1::hash<std::__1::pair<int, int> >, false, false>' required here
template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Вся ошибка здесь (не позволяла мне вставлять выше)

http://fixee.org/paste/528pvoq/

Ответ 1

Это сообщение об ошибке появляется, если вам не удалось выделить std::hash или предоставить хешерный тип для вашего неупорядоченного контейнера (см., например, Использование С++ 11 unordered_set в Visual С++ и clang). Ошибка XCode в этом случае особенно недружелюбна!

С++ 11 не предоставляет хэш для пар (или кортежей), даже для хешируемых типов. Это обсуждение указывает на то, что это произошло в основном из-за нехватки времени, чтобы добиться чего-то лучшего; однако я не знаю, будет ли что-то лучше в С++ 14.

Специализация std::hash<std::pair<int, int>>, вероятно, не очень хорошая идея (и не разрешена языком; специализированные шаблоны std разрешены только для пользовательских типов), поэтому вам нужно предоставить хешер:

struct MoveHasher {
    std::size_t operator()(const std::pair<int, int> &val) const { ... }
};
typedef std::unordered_set<Move, MoveHasher> Set;

См. Как объединить значения хэша в С++ 0x? для того, как писать хэш-функцию.

В качестве альтернативы вы можете сделать Move определяемым пользователем классом (возможно, хорошей идеей!), а затем специализация std::hash будет в порядке.