(I was waiting to Alf Steinbach to post an answer, but since he is not doing it, I will post the reference that he mentioned in the Lounge C++ chat):
The standard indicates that template instantiations are performed after the translation unit has already been translated, so that in time, template instantiations happen after all the non templated elements have already been processed. This is described in section 2.2 Phases of translation:
Paragraphs 1-6 define the preprocessor work and basic textual operations (conversions of the character set, concatenation of literals...)
7/ White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. (2.7). The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
8/ Translated translation units and instantiation units are combined as follows: Each translated translation unit is examined to produce a list of required instantiations. The definitions of the required templates are located. It is implementation-defined whether the source of the translation units containing these definitions is required to be available. All the required instantiations are performed to produce instantiation units. [ Note: These are similar to translated translation units, but contain no references to uninstantiated templates and no template definitions. — end note ] The program is ill-formed if any instantiation fails.
I have removed some of the notes for brevity. Now the important bit seems to be that the code is translated without triggering template instantiations in one step, and then in a later step the templates are instantiated. This in turn means that if the type is complete anywhere in the translation unit, it will have been processed by the time the compiler gets to the instantiation.
Disclaimer: This seems like a good reason for all of the compilers that I have tried showing the exact same behavior (gcc, clang, comeau, VS 2010), but this only states when in time the instantiation is performed, it does not explicitly state that the type can be incomplete at the point of instantiation of the template.
int
to the definition ofX
,sizeof(T)
was 4. Templates have been known in the past to have precognitive abilities. – Seth Carnegie