This code is surely ill-formed, because Foo
is specialized after an instantiation point:
template
struct Foo {
int a;
};
Foo
Fortunatly, yes this is well-defined. For the exact same reason this is well-defined:
struct A;
class Foo { A* value; };
Foo foo; // note A is incomplete here
struct A {};
and this is ill-formed:
struct A;
template class Foo { T value; }; // error: 'Foo::value' has incomplete type
Foo foo; // note A is incomplete here
struct A {};