There are some situations where a template is always invalid, no matter what template arguments are supplied, but the compiler isn't able to figure that out, because it doesn't have the ability to try substituting every possible set of template arguments. According to the standard ([temp.res]/8):
If no valid specialization can
be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic
required.
That means that the compiler is allowed to be smart and prove that there is no valid specialization, and produce a compilation error, but it's also allowed to not be smart enough, and not produce a compilation error. Of course, once the template is instantiated, then the compiler must diagnose the error.
It's not illegal to use the name of a template without template arguments. There are some circumstances where the compiler can deduce arguments. For example:
template <class T>
void foo(T x);
int main() {
void (*p)(int) = foo; // p points to foo<int>
}
In your code, it turns out that you've used Foo
in a context where the template arguments can't be deduced. If the compilers were smarter, they would have figured that out. But the fact that they didn't manage to figure it out does not mean your code is correct.