静态数据成员模板特化的实例化点在哪里

jac*_*k X 8 c++ templates language-lawyer c++17

考虑以下代码:

#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
Run Code Online (Sandbox Code Playgroud)

标准中的 [temp.point] 部分涵盖了实例化点应放置的大多数情况。但是我认为静态数据成员模板还不清楚,因为:

温度点#1

对于函数模板特化、成员函数模板特化或类模板的成员函数或静态数据成员的特化,如果特化是隐式实例化的,因为它是从另一个模板特化和它所在的上下文中引用的引用取决于模板参数,特化的实例化点是封闭特化的实例化点。否则,这种特化的实例化点紧跟在引用该特化的命名空间范围声明或定义之后。

温度点#4

对于类模板特化、类成员模板特化或类模板的类成员的特化,如果特化是隐式实例化的,因为它是从另一个模板特化中引用的,如果引用特化的上下文取决于在模板参数上,如果特化没有在封闭模板的实例化之前实例化,那么实例化点就在封闭模板的实例化点之前。否则,这种特化的实例化点紧跟在引用该特化的命名空间范围声明或定义之前。

两段都分别涵盖了他们提到的情况,他们是a specialization for static data member of a class templatea class member template specialization,所以,静态数据成员模板的特化可以称为a specialization for static data member of a class templatea class member template specialization?我更喜欢把它看作是一个类成员模板特化,我的理由是在第一段,它提到了一个成员函数模板特化,这意味着如果 A 是X模板的特化,它会称之为X模板特化,但是它只是我的推论。

在[temp.static]一节中,表示静态数据成员和静态数据成员模板统称为类的静态数据成员或类模板。

临时静态#1

静态数据成员或静态数据成员模板的定义可以在包含静态成员的类模板定义的命名空间范围内提供。

[注意:静态数据成员模板的特化是静态数据成员。成员函数模板的特化是成员函数。成员类模板的特化是嵌套类。?—?尾注]

现在,措辞使问题更加不清楚。那么根据上面的规则,实例化的点Test<int>::value<int>是在#2还是在#1

如果 的 POITest<int>::value<int>#2,则认为是a specialization for static data member of a class template,否则如果在#1,则认为是a class member template specialization,我不知道哪个位置是正确的。如果我错过了什么,请纠正我。

小智 1

您可能会混淆实例化/专业化

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 Code Online (Sandbox Code Playgroud)

运行此代码https://godbolt.org/z/h434eG,查看输出中数字的顺序,然后取消注释该块并再次运行。

  • 我对“实例化/专业化”并不感到困惑,您的代码似乎无法证明“Test&lt;int&gt;::value&lt;Debug&gt;”的 POI 位于“#1”。如果它位于“#2”,结果仍然与您的代码相同 (2认同)