#include <iostream>
template<typename T>
struct A{
template<typename U>
struct B{};
B<T> b; //#2
};
//#3
int main() {
A<int> a; // #1
}
Consider the above code, the use of the template-id A<int> causes an implicit instantiation for specialization A<int>. According to the following rule:
For a class template specialization, a class member template specialization, or a specialization for a class member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization, if the context from which the specialization is referenced depends on a template parameter, and if the specialization is not instantiated previous to the instantiation of the enclosing template, the point of instantiation is immediately before the point of instantiation of the enclosing template. Otherwise, the point of instantiation for such a specialization immediately precedes the namespace scope declaration or definition that refers to the specialization.
For the specialization referenced at #1, the Otherwise part of that rule will apply to it. That means, the point of instantiation for A<int> should at #3, there's no issue here. However, the instantiation for A<int> will cause the instantiation for specialization B<int> which is a member thereof. Hence, the if part of that rule will apply to B<int>. What I'm confused about is here. According to the relevant rule, the point of instantiation for B<int> shall be immediately before the point of instantiation of the enclosing template, that is, somewhere before #3, I can't understand here. If, think it through the normal class, there're only two ways to define its class member, one is to define the class member in the class definition, the other is to declare the class member in the class definition and then define the class member outside the class definition at some point where follows the classes definition.
Change the example by using a normal class:
struct Normal_A_Int{
struct Normal_B_Int{};
Normal_B_Int b;
};
int main(){
Normal_A_Int a;
}
That means, the definition for member class Normal_B_Int must be in the definition of the enclosing class due to the declaration Normal_B_Int b is required a complete class type.
So, how is it possible to let the definition for member class B<int> be placed at some point precede the definition for an enclosing class A<int>? At best, the definition for B<int> shall be in the definition for A<int>. How to interpret the POI for the first example?