title: Creating an std::unordered_map with an std::pair as key
body: <p>I am trying to create an std::unordered_map with an std::pair as key. As you can imagine, this would require me to explicitly provide a class to generate a hash for a given key, as well as an equality comparator for the keys. Here's my code so far:</p>
  
  <pre><code>#include &lt;unordered_map&gt;
  #include &lt;memory&gt;
  #include &lt;utility&gt;
  
  template &lt;class T, typename U&gt; 
  struct PairHash{ 
      size_t operator()(const std::pair&lt;T, U&gt; &amp;key){ 
          return std::hash&lt;T&gt;()(key.first) ^ std::hash&lt;U&gt;()(key.second);
      }
  };
  
  template &lt;class T, typename U&gt;
  struct PairEqual{
      bool operator()(const std::pair&lt;T, U&gt; &amp;lhs, const std::pair&lt;T, U&gt; &amp;rhs) const{
          return lhs.first == rhs.first &amp;&amp; lhs.second == rhs.second;
      }
  };
  
  struct GraphEdge{
  
  };
  
  
  int main(){
  
      std::unordered_map&lt;std::pair&lt;int, int&gt;, 
                         std::unique_ptr&lt;GraphEdge&gt;, 
                         PairHash&lt;int, int&gt;,
                         PairEqual&lt;int, int&gt;&gt;  edges; 
  
  }
  </code></pre>
  
  <p>However, this gives me a rather (to my eyes at least) inscrutable compiler error:</p>
  
  <pre><code>In file included from /usr/include/c++/5/bits/hashtable.h:35:0,
                   from /usr/include/c++/5/unordered_map:47,
                   from prog.cpp:1:
  /usr/include/c++/5/bits/hashtable_policy.h: In instantiation of 'struct std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt;':
  /usr/include/c++/5/type_traits:137:12:   required from 'struct std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt;'
  /usr/include/c++/5/type_traits:148:38:   required from 'struct std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
  /usr/include/c++/5/bits/unordered_map.h:100:66:   required from 'class std::unordered_map&lt;std::pair&lt;int, int&gt;, std::unique_ptr&lt;GraphEdge&gt;, PairHash&lt;int, int&gt;, PairEqual&lt;int, int&gt; &gt;'
  prog.cpp:29:43:   required from here
  /usr/include/c++/5/bits/hashtable_policy.h:85:34: error: no match for call to '(const PairHash&lt;int, int&gt;) (const std::pair&lt;int, int&gt;&amp;)'
    noexcept(declval&lt;const _Hash&amp;&gt;()(declval&lt;const _Key&amp;&gt;()))&gt;
                                    ^
  prog.cpp:7:12: note: candidate: size_t PairHash&lt;T, U&gt;::operator()(const std::pair&lt;_T1, _T2&gt;&amp;) [with T = int; U = int; size_t = unsigned int] &lt;near match&gt;
       size_t operator()(const std::pair&lt;T, U&gt; &amp;key){ 
              ^
  prog.cpp:7:12: note:   passing 'const PairHash&lt;int, int&gt;*' as 'this' argument discards qualifiers
  In file included from /usr/include/c++/5/bits/move.h:57:0,
                   from /usr/include/c++/5/bits/stl_pair.h:59,
                   from /usr/include/c++/5/utility:70,
                   from /usr/include/c++/5/unordered_map:38,
                   from prog.cpp:1:
  /usr/include/c++/5/type_traits: In instantiation of 'struct std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;':
  /usr/include/c++/5/bits/unordered_map.h:100:66:   required from 'class std::unordered_map&lt;std::pair&lt;int, int&gt;, std::unique_ptr&lt;GraphEdge&gt;, PairHash&lt;int, int&gt;, PairEqual&lt;int, int&gt; &gt;'
  prog.cpp:29:43:   required from here
  /usr/include/c++/5/type_traits:148:38: error: 'value' is not a member of 'std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt;'
       : public integral_constant&lt;bool, !_Pp::value&gt;
                                        ^
  In file included from /usr/include/c++/5/unordered_map:48:0,
                   from prog.cpp:1:
  /usr/include/c++/5/bits/unordered_map.h: In instantiation of 'class std::unordered_map&lt;std::pair&lt;int, int&gt;, std::unique_ptr&lt;GraphEdge&gt;, PairHash&lt;int, int&gt;, PairEqual&lt;int, int&gt; &gt;':
  prog.cpp:29:43:   required from here
  /usr/include/c++/5/bits/unordered_map.h:100:66: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef __umap_hashtable&lt;_Key, _Tp, _Hash, _Pred, _Alloc&gt;  _Hashtable;
                                                                    ^
  /usr/include/c++/5/bits/unordered_map.h:107:45: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::key_type key_type;
                                               ^
  /usr/include/c++/5/bits/unordered_map.h:108:47: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::value_type value_type;
                                                 ^
  /usr/include/c++/5/bits/unordered_map.h:109:48: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::mapped_type mapped_type;
                                                  ^
  /usr/include/c++/5/bits/unordered_map.h:110:43: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::hasher hasher;
                                             ^
  /usr/include/c++/5/bits/unordered_map.h:111:46: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::key_equal key_equal;
                                                ^
  /usr/include/c++/5/bits/unordered_map.h:112:51: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::allocator_type allocator_type;
                                                     ^
  /usr/include/c++/5/bits/unordered_map.h:117:45: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::pointer  pointer;
                                               ^
  /usr/include/c++/5/bits/unordered_map.h:118:50: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::const_pointer const_pointer;
                                                    ^
  /usr/include/c++/5/bits/unordered_map.h:119:47: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::reference  reference;
                                                 ^
  /usr/include/c++/5/bits/unordered_map.h:120:52: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::const_reference const_reference;
                                                      ^
  /usr/include/c++/5/bits/unordered_map.h:121:46: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::iterator  iterator;
                                                ^
  /usr/include/c++/5/bits/unordered_map.h:122:51: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::const_iterator const_iterator;
                                                     ^
  /usr/include/c++/5/bits/unordered_map.h:123:51: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::local_iterator local_iterator;
                                                     ^
  /usr/include/c++/5/bits/unordered_map.h:124:57: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::const_local_iterator const_local_iterator;
                                                           ^
  /usr/include/c++/5/bits/unordered_map.h:125:47: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::size_type  size_type;
                                                 ^
  /usr/include/c++/5/bits/unordered_map.h:126:52: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         typedef typename _Hashtable::difference_type difference_type;
                                                      ^
  /usr/include/c++/5/bits/unordered_map.h:280:7: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         operator=(initializer_list&lt;value_type&gt; __l)
         ^
  /usr/include/c++/5/bits/unordered_map.h:379:2: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
    emplace(_Args&amp;&amp;... __args)
    ^
  /usr/include/c++/5/bits/unordered_map.h:432:7: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         insert(const value_type&amp; __x)
         ^
  /usr/include/c++/5/bits/unordered_map.h:439:2: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
    insert(_Pair&amp;&amp; __x)
    ^
  /usr/include/c++/5/bits/unordered_map.h:499:7: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         insert(initializer_list&lt;value_type&gt; __l)
         ^
  /usr/include/c++/5/bits/unordered_map.h:645:7: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         equal_range(const key_type&amp; __x)
         ^
  /usr/include/c++/5/bits/unordered_map.h:649:7: error: 'value' is not a member of 'std::__not_&lt;std::__and_&lt;std::__is_fast_hash&lt;PairHash&lt;int, int&gt; &gt;, std::__detail::__is_noexcept_hash&lt;std::pair&lt;int, int&gt;, PairHash&lt;int, int&gt; &gt; &gt; &gt;'
         equal_range(const key_type&amp; __x) const
         ^
  </code></pre>
  
  <p>What am I doing wrong?</p>