Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>For static member specializations, if you don't initialize the member, it is taken as a specialization <em>declaration</em>, that just says "Oh, don't instantiate the member from the primary template, because there is a specialized definition somewhere else". It should be mentioned that the definition should appear in a .cpp file (otherwise, you will earn the opposite: multiple definitions), and the declaration without initializer should still be placed in the header file. </p> <p>Now the correct syntax is indeed the following, and it should <em>not</em> appear in a header file, but in a <code>.cpp</code> file</p> <pre><code>template&lt;&gt; int B&lt;A, 1&gt;::a[1] = { }; </code></pre> <p>The following should still appear in a header file:</p> <pre><code>template&lt;&gt; int B&lt;A, 1&gt;::a[1]; </code></pre> <p>This will serve as the specialization <em>declaration</em>.</p> <hr> <p>From this, it follows that you can't specialize a member that only has a default constructor and is not copyable, because you would need this syntax:</p> <pre><code>// needs a copy constructor! template&lt;&gt; Type Class&lt;Arguments&gt;::member = Type(); </code></pre> <p>C++0x fixes this:</p> <pre><code>// doesn't anymore need a copy constructor template&lt;&gt; Type Class&lt;Arguments&gt;::member{}; </code></pre> <hr> <p>For the Standardese people among us, here are the quotes:</p> <p><code>14.7.3/6</code>:</p> <blockquote> <p>If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. </p> </blockquote> <p><code>14.7.3/15</code>:</p> <blockquote> <p>An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. [Note: there is no syntax for the definition of a static data member of a template that requires default initialization. </p> <pre><code>template&lt;&gt; X Q&lt;int&gt;::x; </code></pre> <p>This is a declaration regardless of whether X can be default initialized (8.5). ]</p> </blockquote> <p><code>3.2/3</code>:</p> <blockquote> <p>Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required. </p> </blockquote> <p><code>3.2/5</code>:</p> <blockquote> <p>There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.4) in a program [...]</p> </blockquote> <p>The restriction of this to "for which some template parameters are not specified" means that we <em>are</em> allowed to do the following, placing it into a header (thus possibly having multiple definitions of this specialization):</p> <pre><code>template&lt;&gt; template&lt;typename T&gt; Type OuterClass&lt;int&gt;::InnerClass&lt;T&gt;::StaticMember = 0; </code></pre> <p>In your case, you have all parameters specified, making it not being covered by the one defintion rule for allowing multiple definitions.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload