title: What's the right way to specialize a template when using "extern template"?
body: <p>I am hoping someone can point out the correct way to specialize a method in a template class while using "extern template class" and "template class" for explicit instantiation with gnu c++. I've tried to boil down this problem with the simplest example that mimics my real problem.  It appears that declaring "extern template" implies a template instantiation which causes errors when specializing methods.  Given a driver program:</p>
  
  <p>main.cc</p>
  
  <pre><code>#include A_H
  #include &lt;iostream&gt;
  
  int main()
  {
      A&lt;int&gt; ai;
      A&lt;long&gt; al;
  
      std::cout &lt;&lt; "ai=" &lt;&lt; ai.get() &lt;&lt; " al=" &lt;&lt; al.get() &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p>And the following implemntation of A</p>
  
  <p>a.h</p>
  
  <pre><code>template&lt;typename T&gt;
  struct A
  {
      int get() const;
  };
  
  extern template class A&lt;int&gt;;
  extern template class A&lt;long&gt;;
  </code></pre>
  
  <p>a.cc</p>
  
  <pre><code>#include "a.h"
  
  template&lt;typename T&gt;
  int A&lt;T&gt;::get() const
  {
      return 0;
  }
  
  template&lt;&gt;
  int A&lt;long&gt;::get() const
  {
      return 1;
  }
  
  template class A&lt;int&gt;;
  template class A&lt;long&gt;;
  </code></pre>
  
  <p>I receive the following error when compiling with either, g++ 4.1.2 or 4.4.4</p>
  
  <pre><code> % g++ -Wall -g -D'A_H="a.h"' a.cc main.cc          
  a.cc:10: error: specialization of 'int A&lt;T&gt;::get() const [with T = long int]' after instantiation
   %
  </code></pre>
  
  <p>If I comment out the two "extern template" lines in a.h, things compile and work as expected with both compilers.  I assume depending on the existence of an explicit instantiation in the absence of "extern template" is unspecified behavior even in C++0x, otherwise, what's the point of C++0x adding "extern template"?</p>
  
  <p>If I instead implement A as:</p>
  
  <p>a-hack.h</p>
  
  <pre><code>template&lt;typename T&gt;
  struct A
  {
      int get() const;
  };
  
  template&lt;typename T&gt;
  int A&lt;T&gt;::get() const
  {
      return 0;
  }
  
  template&lt;&gt;
  inline
  int A&lt;long&gt;::get() const
  {
      return 1;
  }
  
  extern template class A&lt;int&gt;;
  extern template class A&lt;long&gt;;
  </code></pre>
  
  <p>a-hack.cc</p>
  
  <pre><code>#include "a-hack.h"
  
  template class A&lt;int&gt;;
  template class A&lt;long&gt;;
  </code></pre>
  
  <p>and compile again, this works as expected</p>
  
  <pre><code>% g++ -Wall -g -D'A_H="a-hack.h"' a-hack.cc main.cc
  % ./a.out 
  ai=0 al=1
  </code></pre>
  
  <p>However, in my real world example, this causes a program crash with g++ 4.1.2 (while working for g++ 4.4.4).  I have not narrowed down the exact cause of the crash (segmentation fault).  It only appears as if the stack pointer is corrupted within what would be the call to A&lt;>::get().</p>
  
  <p>I realize that explicit template instantiation is non-standard at this point, but would anyone expect what I've done above to work?  If not, what is the correct way to do this?</p>
  
  <p>Thanks</p>