I believe the difficulty that was envisioned was that the two instances of Foo<T> actually meant completely different things, because T not the same for both. A few early template implementations (including cfront) used a template repository, so the compiler could automatically create a template over the required type when / if it was discovered that an instance of this type was not in the repository yet.
To make this work with local types, the repository would not just save the type by which the template was created, but instead, it would have to do something like create a complete "path" to the type for instantiation. Although perhaps this is possible, I think it was perceived as most of the extra work for a small (if any) real benefit.
Since then, the rules have changed so much that the compiler already needs to do something roughly equivalent, find (and coalesce) instances of the same type in different places (including through TU) so that two instances of foo<int> (for example) Do not violate ODR. Based on this implementation, the restriction was relaxed in (current project) C ++ 0x (you still cannot create an instance of the template class by the local type, but you can use the local type as a parameter for the template function).
Jerry Coffin
source share