title: Why does in-class initialisation of static members violate the ODR?
body: <p>There are several questions on Stack Overflow along the lines of "why can't I initialise static data members in-class in C++". Most answers quote from the standard telling you <em>what</em> you can do; those that attempt to answer <em>why</em> usually point to a link (now seemingly unavailable) [EDIT: actually it is available, see below] on Stroustrup's site where he states that allowing in-class initialisation of static members would violate the One Definition Rule (ODR).</p>
  
  <p>However, these answers seem overly simplistic. The compiler is perfectly able to sort out ODR problems when it wants to. For example, consider the following in a C++ header:</p>
  
  <pre><code>struct SimpleExample
  {
      static const std::string str;
  };
  
  // This must appear in exactly one TU, not a header, or else violate the ODR
  // const std::string SimpleExample::str = "String 1";
  
  template &lt;int I&gt;
  struct TemplateExample
  {
      static const std::string str;
  };
  
  // But this is fine in a header
  template &lt;int I&gt;
  const std::string TemplateExample&lt;I&gt;::str = "String 2";
  </code></pre>
  
  <p>If I instantiate <code>TemplateExample&lt;0&gt;</code> in multiple translation units, compiler/linker magic kicks in and I get exactly one copy of <code>TemplateExample&lt;0&gt;::str</code> in the final executable.</p>
  
  <p>So my question is, given that it's obviously possible for the compiler to solve the ODR problem for static members of template classes, why can it not do this for non-template classes too?</p>
  
  <p><strong>EDIT</strong>: The Stroustrup FAQ response is available <a href="http://www.stroustrup.com/bs_faq2.html#in-class" rel="nofollow">here</a>. The relevant sentence is:</p>
  
  <blockquote>
    <p>However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects</p>
  </blockquote>
  
  <p>It seems however that those "complicated linker rules" do exist and are used in the template case, so why not in the simple case too?</p>