title: c++ std::tr1::hash::operator() undefined?
body: <p>I'm converting a C++ program over from Windows building with Visual C++ 2008 to build on Linux with gcc 4.6.1. There's a module that uses <code>&lt;unordered_map&gt;</code>. In VC++, it seems to be perfectly ok to </p>
  
  <pre><code>#include &lt;unordered_map&gt;
  
  ...
  
  
  
  std::tr1::unordered_map&lt;mystruct, int&gt; my_map;
  </code></pre>
  
  <p>We're actually supporting more compilers than just gcc 4.6 and VC++ 2008, so using pure C++2011 code isn't feasible. gcc gets upset with <code>#include &lt;unordered_map&gt;</code>, complaining that this is the true-blue c++2011 include file, so one of the things I had to do to make this work was change the include to </p>
  
  <pre><code>#include &lt;tr1/unordered_map&gt;
  
  ...
  
  
  std::tr1::unordered_map&lt;mystruct, int&gt; my_map;
  </code></pre>
  
  <p>This works. Fair enough. Now I've got another problem, though. Here's the definition for mystruct:</p>
  
  <pre><code>struct mystruct
  {
  #ifdef __cplusplus
      inline operator size_t() const
      {
          return m_val;
      }
  #endif
      unsigned int m_val;
  };
  </code></pre>
  
  <p>In VC++ 2008, this seems to be as much as <code>std::hash</code> needs to specialize on <code>mystruct</code>. <code>std::tr1::hash</code>, on the other hand, doesn't like this, at least not on gcc 4.6.1. It refuses to link, complaining that <code>std::tr1::hash&lt;mystruct&gt;::operator()( mystruct ) const</code> is undefined. I'm not sure whether that happens with VC++ when I do the proper <code>tr1</code> include - maybe it'll complain about the same thing? I'll try it tomorrow, but for now all I've got is a linux box with gcc on it. For now, I had to do this to get it working:</p>
  
  <pre><code>namespace std {
      namespace tr1 {
          std::size_t hash&lt;mystruct&gt;::operator()( mystruct &amp; c ) const 
          { 
              return c.m_val; 
          }
      }
  }
  </code></pre>
  
  <p>Can anyone enlighten me on how this is supposed to work? It seems so much more elegant to be able to define a <code>size_t</code> operator on a type that you want to be hashable, but I'm willing to live with defining the <code>operator()</code> on <code>std::tr1::hash</code>.</p>
  
  <p>UPDATE:</p>
  
  <p>I tried specializing the entire hash class, as suggested. Building with gcc, I get</p>
  
  <pre><code>myfile.cpp:41:12: error: specialization of 'std::tr1::hash&lt;mystruct&gt;' after instantiation
  myfile.cpp:41:12: error: redefinition of 'struct std::tr1::hash&lt;mystruct&gt;'
  /usr/include/c++/4.6/tr1/functional_hash.h:45:12: error: previous definition of 'struct std::tr1::hash&lt;mystruct&gt;'
  </code></pre>