title: Why does this compile, Template deduction should fail?
body: <p>I'm attempting to write a serialiser. The following code compiles:</p>
  
  <pre><code>#include &lt;string&gt;
  #include &lt;fstream&gt;
  #include &lt;type_traits&gt;
  #include &lt;map&gt;
  #include &lt;iostream&gt;
  
  class SpaceStream
  {
  public:
  
      SpaceStream(const std::string&amp; filename)
      :
          m_file(filename)
      {
      }
  
      template&lt;typename T&gt;
      typename std::enable_if&lt;std::is_class&lt;T&gt;::value&gt;::type
      Add(const std::string&amp; key, const T&amp; t)
      {
          m_file &lt;&lt; key;
          m_file &lt;&lt; ":{";
          t.Serialise(*this);
          m_file &lt;&lt; "},";
      }
  
      template&lt;typename T&gt;
      typename std::enable_if&lt;!std::is_class&lt;T&gt;::value &amp;&amp; !std::is_pointer&lt;T&gt;::value &amp;&amp; !std::is_reference&lt;T&gt;::value&gt;::type
      Add(const std::string&amp; key, const T t)
      {
          m_file &lt;&lt; key;
          m_file &lt;&lt; ':';
          m_file &lt;&lt; t;
          m_file &lt;&lt; ',';
      }
  
  private:
      std::ofstream m_file;
      std::map&lt;std::string,std::string&gt; m_pointerObj;
  };
  
  
  class ISerialise
  {
  public:
      virtual void Serialise(SpaceStream&amp; stream) const = 0;
  };
  
  class Test1 : public ISerialise
  {
  public:
      int m_x;
      int&amp; m_rx;
  
      Test1(int&amp; x)
      :
          m_x(x), m_rx(x)
      {
      }
  
      virtual void Serialise(SpaceStream&amp; stream) const
      {
          stream.Add("x",m_x);
          stream.Add("xr",m_rx);
      }
  };
  
  int main()
  {
      int j = 13;
      Test1 test(j);
      j = 23;
  
      SpaceStream ss("somefile.ss");
      ss.Add("testobj",test);
  }
  </code></pre>
  
  <p>I'd have thought that this line:</p>
  
  <pre><code>stream.Add("xr",m_rx);
  </code></pre>
  
  <p>would have failed because of the two <code>Add</code> functions, one specifically checks that the type isn't a class, the other checks that it's not a reference. <code>m_rx</code> is a reference type, so it should fail?</p>
  
  <p><strong>EDIT</strong>
  I understand now that the type is actually a value and not a reference. I need to be able to identify references so that I can keep track of them (I only want to serialise the data once, and reference it).</p>