Consider the below code:
#include <iostream>
template<typename T>
struct Test{
template<typename U>
static U value;
};
template<typename T>
template<typename U>
U Test<T>::value = U{};
//#1
int main(){
auto d = Test<int>::value<int>;
}
//#2
The [temp.point] section in the standard covers the most case of where the point of instantiation shall place. However I think it's unclear about static data member template, due to:
For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
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.
Two paragraphs all respectively cover the case they mentioned, they are a specialization for static data member of a class template
and a class member template specialization
, So, the specialization for static data member template could be called a specialization for static data member of a class template
or a class member template specialization
? I prefer to consider it as a class member template specialization, My reason is in the first paragraph, it has mentioned a member function template specialization, that implies if A is a specialization for X
template, it would call it a X
template specialization, however It's just my inference.
In the section of [temp.static], it implies that a static data member and static data member template are collectively called static data member of class or class template.
A definition for a static data member or static data member template may be provided in a namespace scope enclosing the definition of the static member's class template.
[Note: A specialization of a static data member template is a static data member. A specialization of a member function template is a member function. A specialization of a member class template is a nested class. — end note]
Now, the wording makes the question more unclear. So according to the above rules, Is the point of instantiation for Test<int>::value<int>
is at #2
or #1
?
If the POI of Test<int>::value<int>
is at #2
, then it will be considered as a specialization for static data member of a class template
, otherwise if it's at #1
, then it will be considered as a class member template specialization
, I don't know which the position is correct. If I miss something, please correct me.
ANamespace::Test<T>::value
– Swift - Friday Pie