I find it perfectly reasonable, and the committee has more of that pleasure . Therefore, I think that I probably have some errors in the below. So please read it with care :)
Third paragraph
For specialization of a class template, specialization of a class member template, or specialization for a class member of a class template, if the specialization is implicitly created because it is referenced from another template specialization if the context from which the specialization refers to the template parameter and if the specialization is not created before creation instance of the closing template, the instantiation point is immediately in front of the instantiation point of the covering template.
In other words, if an instance is created of a class template or a nested class of a class template, and the context that triggers this event depends on the template parameter, the template / nested class is created immediately before the instantiation point of the template that references it.
The context in another specialization can either depend on the template parameters, as for primary templates, partial specializations and members of the class template, or it does not depend on the template parameters, which is the case for explicit references from within.
Otherwise [i.e. context did not depend], the instance point for such a specialization immediately precedes the declaration or definition of the namespace area that relates to the specialization.
This distinction is important. Think about what happens if the instantiation point for specializations from dependent contexts immediately precedes the declaration of the namespace scope or the definition that refers to it
template<typename T, int N> struct A { typedef typename A<T, N-1>::type *type; }; template<typename T> struct A<T, 0> { typedef T type; }; typedef A<int, 2>::type ptr;
This template should add N pointer declarators. So A<int, 2> is int** , for example.
- The context around
typedef A<int, 2>::type is independent, so A<int, 2> is created before the typedef declaration. In A<int, 2> we have A<int, N-1>::type , which appears in a dependent context and which refers to A<int, 1>::type . Therefore, the Standard requires that we create an instance of A<int, 1> at the same point at which we created an instance of A<int, 2> .
If we imagine this immediately before declaring the namespace scope that referred to it (before defining the primary template), we would not notice a partial specialization of A<T, 0> when processing `A<int, N-1>::type inside A<int, 1> because we will instantiate A<int, 1> before this specialization.
Second paragraph
Itβs just that the names found in the default arguments are consistent with the names that were looked at in the rest of the function for which they are used (i.e. their POI matches the POI of their template function / member function of the template class) .
First paragraph
This is basically the same as in the third paragraph. However, function templates are created after the object that references them so that recursive use can be used, as in the following example. In contrast, class templates are created in front of an entity that references them because the object requires the class type to be completed. If the class type of the POI is after this object, the class type will still be absent.
template<typename T> void f(T); template<typename T> struct A { void g() { f(0); } void h() { } }; template<typename T> void f(T t) { A<T> a; ah(); } void g() { A<int> a; ag(); }
If f is created before A<int> , then it will not be able to access ah() , because at that moment it did not exist. Therefore, function templates are created after the object that refers to them, and class templates are created in front of the entity that refers to them.