It has to have separate template
clauses for each template that is involved. Here, two templates are involved, that all deserve their (non-empty) template clauses:
- The class template
Foo
- The constructor template
Consider this case which fails because of the ambiguity as to where the parameter U
belongs to
template<typename T>
struct A {
template<typename U> void f();
};
template<typename T, typename U>
void A<T>::f() { }
Now, what is up with the parameter U
? Sure the compiler could guess it could belong to f
, but guesswork is not what the compiler likes :) The existing rule says that depending on the nesting of templates, template clauses appear in the right order. Everything is clear then.
Even if one comes up with a rule how to match the parameters to arguments of the templates involved (so far i don't see a real difficulty in doing that), it would be inconsistent. Because as of now, one template clause lists all parameters that the corresponding template accepts. Much like a function parameter list. If we would put everything into one clause, that clear semantic could be broken - not to mention that when we put the definition into the class again, all of a sudden the template would get its own clause:
// provides arguments for A's parameters, then for f ones
// when it's called
A<int> a;
a.f<bool>();
It's much more natural when we have separate template clauses that catch each their own arguments. So, the syntax for the above wrong definition is
template<typename T>
template<typename U>
void A<T>::f() { }
Now, also the reader of the code immediately sees that this is a definition of a member template, and not a (potential accidentally declared but unused) second parameter for A
.