title: implicit instantiation of undefined template 'class'
body: <p>When trying to offer functions for const and non-const template arguments in my library I came across a strange problem. The following source code is a minimal example phenomenon:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  
  template&lt;typename some_type&gt;
  struct some_meta_class;
  
  template&lt;&gt;
  struct some_meta_class&lt;int&gt;
  {
      typedef void type;
  };
  
  
  
  template&lt;typename some_type&gt;
  struct return_type
  {
      typedef typename some_meta_class&lt; some_type &gt;::type test;
  
      typedef void type;
  };
  
  
  
  template&lt;typename type&gt;
  typename return_type&lt;type&gt;::type foo( type &amp; in )
  {
      std::cout &lt;&lt; "non-const" &lt;&lt; std::endl;
  }
  
  template&lt;typename type&gt;
  void foo( type const &amp; in )
  {
      std::cout &lt;&lt; "const" &lt;&lt; std::endl;
  }
  
  
  int main()
  {
      int i;
  
      int const &amp; ciref = i;
      foo(ciref);
  }
  </code></pre>
  
  <p>I tried to implement a non-const version and a const version for foo but unfortunately this code won't compile on CLANG 3.0 and gcc 4.6.3.</p>
  
  <blockquote>
    <p>main.cpp:18:22: error: implicit instantiation of undefined template
    'some_meta_class'</p>
  </blockquote>
  
  <p>So for some reason the compiler wants to use the non-const version of foo for a const int-reference. This obviously leads to the error above because there is no implementation for some_meta_class. The strange thing is, that if you do one of the following changes, the code compile well and works:</p>
  
  <ul>
  <li>uncomment/remove the non-const version</li>
  <li>uncomemnt/remove the typedef of return_type::test</li>
  </ul>
  
  <p>This example is of course minimalistic and pure academic. In my library I came across this problem because the const and non-const version return different types. I managed this problem by using a helper class which is partially specialized.</p>
  
  <p>But why does the example above result in such strange behaviour? Why doesn't the compiler want to use the non-const version where the const version is valid and and matches better?</p>