The timing of C++ template instantiation
<p>I wonder if anyone knows why the following two pieces of code behave very differently.  I can understand why the second one doesn't work, but why does the first one work?  At the same place <code>int x = gc.f();</code> the template should get instantiated so the same error would occur, but why actually there is no error?</p>

<p><strong>a.cpp</strong></p>

<pre><code>#include &lt;iostream&gt;

using namespace std;

template &lt;typename T&gt;
struct A {
    struct B {
    };
};

template &lt;typename T&gt;
struct C {
    typedef A&lt;C&lt;T&gt; &gt; D;

    int f() {
        typename D::B p;
        return 0;
    }
};

C&lt;float&gt; gc;
int x = gc.f();

template &lt;typename T&gt;
struct A&lt;C&lt;T&gt; &gt; {
    struct B {
        B() {
            cout &lt;&lt; "B::B()" &lt;&lt; endl;
        }

        ~B() {
            cout &lt;&lt; "B::~B()" &lt;&lt; endl;
        }
    };
};

int main() {
}
</code></pre>

<p><strong>output</strong></p>

<pre><code>B::B()
B::~B()
</code></pre>

<p>and</p>

<p><strong>a2.cpp</strong></p>

<pre><code>#include &lt;iostream&gt;

using namespace std;

template &lt;typename T&gt;
struct A {
    struct B {
    };
};

struct C {
    typedef A&lt;C&gt; D;

    int f() {
        D::B p;
        return 0;
    }
};

C gc;
int x = gc.f();

template &lt;&gt;
struct A&lt;C&gt; {
    struct B {
        B() {
            cout &lt;&lt; "B::B()" &lt;&lt; endl;
        }

        ~B() {
            cout &lt;&lt; "B::~B()" &lt;&lt; endl;
        }
    };
};

int main() {
}
</code></pre>

<p><strong>compiler error</strong></p>

<pre><code>a2.cpp:24: error: specialization of ‘A&lt;C&gt;’ after instantiation
a2.cpp:24: error: redefinition of ‘struct A&lt;C&gt;’
a2.cpp:6: error: previous definition of ‘struct A&lt;C&gt;’
</code></pre>
