title: Understanding C++ member function template specialization
body: <p>I have the following class:</p>
  
  <pre><code>#pragma once
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  
  class testclass
  {
  public:
      template &lt;class T&gt; T item(const std::string&amp; key)
      {
          std::cout &lt;&lt; "non-specialized\n";
          return T();
      }
  };
  </code></pre>
  
  <p>For the item method I would like to provide a specialization for strings. I try to do this the following way (in testclass.cpp):</p>
  
  <pre><code>#include "testclass.h"
  #include &lt;iostream&gt;
  
  template&lt;&gt; std::string testclass::item(const std::string&amp; key)
  {
      std::cout &lt;&lt; "specialized\n";
      return std::reverse(key.begin(), key.end());
  }
  </code></pre>
  
  <p>And then I try to call the function like this:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "testclass.h"
  
  int main()
  {
      testclass t;
      std::string key = "foo";
      t.item&lt;int&gt;(key);
      std::string s = t.item&lt;std::string&gt;(key);
      std::cout &lt;&lt; s &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>However, the output is</p>
  
  <pre><code>$ ./a.out
  non-specialized 
  non-specialized
  (empty line)
  </code></pre>
  
  <p>What I excepted was</p>
  
  <pre><code>$ ./a.out
  non-specialized 
  specialized
  oof
  </code></pre>
  
  <p>How can I do this properly? I am using g++ 4.5.2 to compile the program. </p>
  
  <p><strong>Edit</strong>:</p>
  
  <p>The solution is the move the whole definition of the specialization of <code>item</code> to testclass.h (but not into the class). I had other mistakes in the program, such as not including <code>&lt;algorithm&gt;</code> (for reverse), and incorrectly thinking that it would return the reversed string. To achieve the excepted behaviour, the .cpp file is left empty, and the header contents are the following:</p>
  
  <pre><code>#pragma once
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  #include &lt;algorithm&gt;
  
  class testclass
  {
      public:
          template &lt;class T&gt; T item(const std::string&amp; key)
          {
              std::cout &lt;&lt; "non-specialized\n";
              return T();
          }
  };
  
  template&lt;&gt; std::string testclass::item(const std::string&amp; key)
  {
      std::cout &lt;&lt; "specialized\n";
      std::string s = key;
      std::reverse(s.begin(), s.end());
      return s;
  }
  </code></pre>