This code is surely ill-formed, because Foo
is specialized after an instantiation point:
template
struct Foo {
int a;
};
Foo
Assuming we only have one translation unit, [temp.point] rules out your quote as a possible source of ill-formedness
A specialization for a class template has at most one point of instantiation within a translation unit.
Instead, the problem with the first snippet is [temp.expl.spec]
If a template, a member template or a 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.
The second snippet is well-formed, there is no requirement that template parameters need to have complete type.
The third snippet is ill-formed, new T
requires that T
be a complete type. A slight catch here is that the definition of the constructor is implicitly instantiated at Foo foo;
. If however, the snippet is changed to
struct A;
template
struct Foo {
Foo() {
new T;
}
};
using FooA = Foo;
struct A {};
Then the definition of the constructor isn't instantiated and will therefore be well-formed. [temp.inst]
The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends; and [...]
The fourth snippet is ill-formed because members need to have complete type. [class.mem]
The type of a non-static data member shall not be an incomplete type [...]