title: Why does this template function not behave as expected?
body: <p>I was reading about template functions and got confused by this problem:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  void f(int) {
      std::cout &lt;&lt; "f(int)\n";
  }
  
  template&lt;typename T&gt;
  void g(T val) {
      std::cout &lt;&lt; typeid(val).name() &lt;&lt; "  ";
      f(val);
  }
  
  void f(double) {
      std::cout &lt;&lt; "f(double)\n";
  }
  
  template void g&lt;double&gt;(double);
  
  int main() {
      f(1.0); // f(double)
      f(1);   // f(int)
      g(1.0); // d  f(int), this is surprising
      g(1);   // i  f(int)
  }
  </code></pre>
  
  <p>The results are the same if I don't write <code>template void g&lt;double&gt;(double);</code>.</p>
  
  <p>I think <code>g&lt;double&gt;</code> should be instantiated after <code>f(double)</code>, and therefore the call to <code>f</code> in <code>g</code> should call <code>f(double)</code>. Surprisingly, it still calls <code>f(int)</code> in <code>g&lt;double&gt;</code>. Can anyone help me understand this?</p>
  
  <hr>
  
  <p>After reading the answers, I figured out what my confusion really is.</p>
  
  <p>Here is an updated example. It is mostly unchanged except that I added a specialization for <code>g&lt;double&gt;</code>:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  void f(int){cout &lt;&lt; "f(int)" &lt;&lt; endl;}
  
  template&lt;typename T&gt;
  void g(T val)
  {
      cout &lt;&lt; typeid(val).name() &lt;&lt; "  ";
      f(val);
  }
  
  void f(double){cout &lt;&lt; "f(double)" &lt;&lt; endl;}
  
  //Now use user specialization to replace
  //template void g&lt;double&gt;(double);
  
  template&lt;&gt;
  void g&lt;double&gt;(double val)
  {
      cout &lt;&lt; typeid(val).name() &lt;&lt; "  ";
      f(val);
  }
  
  int main() {
      f(1.0); // f(double)
      f(1);  // f(int)
      g(1.0); // now d  f(double)
      g(1);  // i  f(int)
  }
  </code></pre>
  
  <p>With the user specialization, <code>g(1.0)</code> behaves as I expected.</p>
  
  <p>Should the compiler not automatically do this same instantiation for <code>g&lt;double&gt;</code> in the same place (or even after <code>main()</code>, as described in section 26.3.3 of <em><a href="https://en.wikipedia.org/wiki/The_C%2B%2B_Programming_Language" rel="noreferrer">The C++ Programming Language</a></em>, 4th edition)?</p>