title: C++ template function compiles in header but not implementation
body: <p>I'm trying to learn templates and I've run into this confounding error.  I'm declaring some functions in a header file and I want to make a separate implementation file where the functions will be defined.</p>
  <p>Here's the code that calls the header (<code>dum.cpp</code>):</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  #include &lt;string&gt;
  #include &quot;dumper2.h&quot;
  
  int main() {
      std::vector&lt;int&gt; v;
      for (int i=0; i&lt;10; i++) {
          v.push_back(i);
      }
      test();
      std::string s = &quot;, &quot;;
      dumpVector(v,s);
  }
  </code></pre>
  <p>Now, here's a working header file (<code>dumper2.h</code>):</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  void test();
  
  template &lt;class T&gt; void dumpVector(const std::vector&lt;T&gt;&amp; v,std::string sep);
  
  template &lt;class T&gt; void dumpVector(const std::vector&lt;T&gt;&amp; v, std::string sep) {
      typename std::vector&lt;T&gt;::iterator vi;
  
      vi = v.cbegin();
      std::cout &lt;&lt; *vi;
      vi++;
      for (;vi&lt;v.cend();vi++) {
          std::cout &lt;&lt; sep &lt;&lt; *vi ;
      }
      std::cout &lt;&lt; &quot;\n&quot;;
      return;
  }
  </code></pre>
  <p>With implementation (<code>dumper2.cpp</code>):</p>
  <pre><code>#include &lt;iostream&gt;
  #include &quot;dumper2.h&quot;
  
  void test() {
      std::cout &lt;&lt; &quot;!olleh dlrow\n&quot;;
  }
  </code></pre>
  <p>The weird thing is that if I move the code that defines <code>dumpVector</code> from the <code>.h</code> to the <code>.cpp</code> file, I get the following error:</p>
  <pre><code>g++ -c dumper2.cpp -Wall -Wno-deprecated
  g++ dum.cpp -o dum dumper2.o -Wall -Wno-deprecated
  /tmp/ccKD2e3G.o: In function `main':
  dum.cpp:(.text+0xce): undefined reference to `void dumpVector&lt;int&gt;(std::vector&lt;int, std::allocator&lt;int&gt; &gt;, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)'
  collect2: ld returned 1 exit status
  make: *** [dum] Error 1
  </code></pre>
  <p>So why does it work one way and not the other?  Clearly the compiler can find <code>test()</code>, so why can't it find <code>dumpVector</code>?</p>