title: Avoiding duplicate symbol due to initialization of specialization in header?
body: <p>I'm catching duplicate symbol errors due to definitions I am trying to provide in a header. Here's the error from the <a href="http://stackoverflow.com/help/mcve">Minimal, Complete, and Verifiable example</a>. The header files and source files are shown below.</p>
  
  <pre><code>$ clang++ main.cpp x.cpp y.cpp -o main.exe 2&gt;&amp;1 | c++filt
  duplicate symbol Id&lt;S&gt;::id in:
      /tmp/main-3f2415.o
      /tmp/long long-d62c28.o
  duplicate symbol Id&lt;T&gt;::id in:
      /tmp/main-3f2415.o
      /tmp/long long-d62c28.o
  duplicate symbol Id&lt;S&gt;::id in:
      /tmp/main-3f2415.o
      /tmp/unsigned long long-bfa6de.o
  duplicate symbol Id&lt;T&gt;::id in:
      /tmp/main-3f2415.o
      /tmp/unsigned long long-bfa6de.o
  ld: 4 duplicate symbols for architecture x86_64
  </code></pre>
  
  <p>Here is a similar question, but it does not involve a specialization: <a href="https://stackoverflow.com/q/3229883/608639">Static member initialization in a class template</a>. This question has the specialization but it is for MSVC and not Clang: <a href="https://stackoverflow.com/q/11153182/608639">How to initialize a static member of a parametrized-template class</a>. And this question states to put it in the source (*.cpp) file but we are aiming for the header file to avoid Clang 3.8 and <em><code>'Id&lt;S&gt;::id' required here, but no definition is available</code></em> warnings: <a href="https://stackoverflow.com/q/47544299/608639">Where should the definition of an explicit specialization of a class template be placed in C++?</a></p>
  
  <p>GCC, ICC, MSVC, SunCC and XLC are OK with the initialization. Clang and LLVM is giving me the trouble. Clang and LLVM also has trouble with explicit instantiations of specializations and <code>extern</code>, so its it own special kind of hell.</p>
  
  <p>We support C++03 though C++17, so we have to be careful of the solution. Naively I tried placing the initialization of the specializations in an unnamed namespace to keep the symbols from escaping the translation units, but it resulted in compile errors.</p>
  
  <p>How do we avoid duplicate symbol definitions when initializing and specializing a template class in a header?</p>
  
  <hr>
  
  <p>Below is the MCVE, which is a <code>cat main.cpp a.h s.h s.cpp t.h t.cpp x.cpp y.cpp</code>. The problem seems to be with <code>a.h</code>, which provides the specialization and initialization; and the source files <code>x.cpp</code> and <code>y.cpp</code>, which include <code>a.h</code>.</p>
  
  <p><strong><em>main.cpp</em></strong></p>
  
  <pre><code>#include "a.h"
  #include "s.h"
  #include "t.h"
  
  int main(int argc, char* argv[])
  {
      uint8_t s = Id&lt;S&gt;::id;
      uint8_t t = Id&lt;T&gt;::id;
      return 0;
  }
  </code></pre>
  
  <p><strong><em>a.h</em></strong></p>
  
  <pre><code>#ifndef A_INCLUDED
  #define A_INCLUDED
  
  #include &lt;stdint.h&gt;
  
  template &lt;class T&gt; class Id
  {
  public:
      static const uint8_t id;
  };
  
  class S;
  class T;
  
  template&lt;&gt; const uint8_t Id&lt;S&gt;::id = 0x01;
  template&lt;&gt; const uint8_t Id&lt;T&gt;::id = 0x02;
  
  #endif
  </code></pre>
  
  <p><strong><em>s.h</em></strong></p>
  
  <pre><code>#ifndef S_INCLUDED
  #define S_INCLUDED
  
  class S {
  public:
      S();
  };
  
  #endif
  </code></pre>
  
  <p><strong><em>s.cpp</em></strong></p>
  
  <pre><code>#include "s.h"
  
  S::S() {}
  </code></pre>
  
  <p><strong><em>t.h</em></strong></p>
  
  <pre><code>#ifndef T_INCLUDED
  #define T_INCLUDED
  
  class T {
  public:
      T();
  };
  
  #endif
  </code></pre>
  
  <p><strong><em>t.cpp</em></strong></p>
  
  <pre><code>#include "t.h"
  
  T::T() {}
  </code></pre>
  
  <p><strong><em>x.cpp</em></strong></p>
  
  <pre><code>#include "a.h"
  </code></pre>
  
  <p><strong><em>y.cpp</em></strong></p>
  
  <pre><code>#include "a.h"
  </code></pre>