考虑下面的代码:
#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
标准中的 [temp.point] 部分涵盖了实例化点应放置的大多数情况。但是我认为静态数据成员模板尚不清楚,因为:
温度点#1 https://timsong-cpp.github.io/cppwp/n4659/temp.point#1
对于函数模板专业化、成员函数模板专业化,或者类模板的成员函数或静态数据成员的特化,如果特化是隐式实例化的,因为它是从另一个模板特化内部引用的,并且引用它的上下文依赖于模板参数,则特化的实例化点就是封闭特化的实例化点。否则,此类专业化的实例化点紧跟在引用该专业化的命名空间范围声明或定义之后。
温度点#4 https://timsong-cpp.github.io/cppwp/n4659/temp.point#4
对于类模板专业化,类成员模板特化,或类模板的类成员的特化,如果特化是隐式实例化的,因为它是从另一个模板特化中引用的,如果引用特化的上下文依赖于模板参数,并且如果特化不是在封闭模板的实例化之前实例化,实例化点紧接在封闭模板的实例化点之前。否则,此类专门化的实例化点立即位于引用该专门化的名称空间范围声明或定义之前。
两段分别涵盖了他们提到的情况,他们是a specialization for static data member of a class template
and a class member template specialization
,所以,专业化为静态数据成员模板可以称为a specialization for static data member of a class template
or a class member template specialization
?我更愿意将其视为类成员模板特化,我的理由在第一段中已经提到了成员函数模板特化,这意味着如果 A 是X
模板,它会称之为X
模板专业化,但这只是我的推断。
在 [temp.static] 部分中,它意味着静态数据成员和静态数据成员模板统称为类或类模板的静态数据成员。
临时静态#1 https://timsong-cpp.github.io/cppwp/n4659/temp.static#1
静态数据成员或静态数据成员模板的定义可以在包含静态成员的类模板的定义的命名空间范围中提供。
[注意:静态数据成员模板的特化是静态数据成员。成员函数模板的特化是成员函数。成员类模板的特化是嵌套类。 —— 尾注]
现在,措辞使问题更加不清楚。那么根据上面的规则, 实例化点就是Test<int>::value<int>
is at #2
or #1
?
如果 POI 为Test<int>::value<int>
is at #2
,那么它将被视为a specialization for static data member of a class template
,否则如果它位于#1
,那么它将被视为a class member template specialization
,我不知道哪个立场是正确的。如果我遗漏了什么,请纠正我。