If I read the standard correctly, I don't believe your code is ill-formed (bar the use of a _T
identifier). Clang going the extra mile is fantastic, but GCC isn't wrong to accept it as is.
The reason is your program only contains an implicit instantiation of your template. According to N19051 (emphasis mine):
14.7.1 Implicit instantiation [temp.inst]
1 ... The implicit instantiation of a class
template specialization causes the implicit instantiation of the
declarations, but not of the definitions or default arguments, of the
class member functions, member classes, static data members and member
templates; and it causes the implicit instantiation of the definitions
of member anonymous unions. Unless a member of a class template or a
member template has been explicitly instantiated or explicitly
specialized, the specialization of the member is implicitly
instantiated when the specialization is referenced in a context that
requires the member definition to exist; in particular, the
initialization (and any associated side-effects) of a static data
member does not occur unless the static data member is itself used in
a way that requires the definition of the static data member to exist.
Nothing uses object_creator
in a way that requires its definition to exist. As such only the declaration is ever checked. Furthermore, only the declaration of class ObjectCreator
is required to be instantiated itself, not its definition (or the definition of its constructor). This is for the same reason one can define an extern variable of a forward declared class type:
extern class C c;
The above paragraph (and the fact nothing uses object_creator
) only requires the type name and object name be instantiated, to produce an effect similar to the above external declaration.
As a result GCC never has to verify instance
is valid. I would say that given the above paragraph, even if you didn't have a typo, it's quite possible object_creator
doesn't do what you think it does. If your code worked, it's only because the function local static obj
was initialized on first use (making ObjectCreator
redundant).
As for why adding an explicit instantiation (like @P i suggested) immediately causes an error. We can see here:
14.7.2 Explicit instantiation [temp.explicit]
7 The explicit instantiation of a class template
specialization also explicitly instantiates each of its members (not
including members inherited from base classes) whose definition is
visible at the point of instantiation and that has not been previously
explicitly specialized in the translation unit containing the explicit
instantiation.
When we do that, we recursively force everything to be instantiated, and as a result, checked.
1 - This is a 2005 draft. Very close to C++03, and therefore I believe appropriate given your use of GCC 4.4.7.