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:
temp.point#1
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.
temp.point#4
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.
temp.static#1
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.
This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming. Generic programming is an approach where generic data types are used as parameters in algorithms so that they work for variety of suitable data types.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
You may be confusing instantiation/specialization
template<typename T>
template<typename U>
U Test< T >::value = 88; // <- this is not specialization
template<>
template<>
int Test< int >::value<int> = 98; // <- this is specialization
Run this code https://godbolt.org/z/h434eG, take a look at the order of the numbers on the output, then uncomment the block with a specialization and run again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With