模板的静态成员

Static member of template

本文关键字:静态成员      更新时间:2023-10-16

这里有一个类似的问题,但它与带有typename关键字的模板有关。

给定一个模板:

template < int X, char Y >
struct foo
{
    char myArray[ X <= 0 ? 1 : X ];
    static const char Z = Y;
}

该静态成员是否会在foo的所有实例之间共享,或者编译器会看到已使用不同的参数调用模板并创建新类型?

在那里分配的静态常量成员根据模板参数传递的值而变化。将其缩短为如下所示:

template<int X>
struct foo { 
    static const int value = X;
};

你不会期望foo<10>::value等于foo<11>::value吧?这通常用于模板元编程,因为该静态常量的值取决于模板参数。

实际上,您定义的模板参数是非类型参数,而不是其他两种模板参数:类型参数和模板参数。

但是,它们仍然是模板参数,您将为每个不同的模板参数集获得一个全新的数据类型。例如,foo<3,'a'> 是与 foo<4,'a'> 不同的数据类型,而 又不同于 foo<3,'b'> 等。

因此,静态成员也为每个模板参数的选择单独分配和初始化。

在这方面,非类型参数、类型参数和模板参数的工作方式都相同。


作为参考,来自标准(C++11(:

(§14.7/6(从模板实例化的每个类模板专用化都有自己的静态成员副本。[ 示例:

template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;

X<int>有一个int类型的静态成员sX<char*>有一个char*类型的静态成员s

上面标准给出的示例提到了类型参数,但第 14.7/6 节是模板一般讨论的一部分。更广泛的上下文清楚地表明,这适用于使用非类型参数(或类型、非类型和模板参数的组合(的模板。

还有一个关于模板实例化

的类型等效性的部分,它解释了在什么情况下使用非类型参数的模板实例化被认为是相等的(相关部分由我强调(:

(§14/1( 两个模板 ID 引用同一个类或函数,如果
— 它们的模板名称、运算符函数 ID 或文字运算符 ID 引用相同的模板和
— 它们对应的类型模板参数是相同的类型,并且
— 它们对应的整型或枚举型非类型模板参数具有相同的值
— 它们对应的指针类型的非类型模板参数引用相同的外部对象或函数,或者既是空指针值又
是空指针值 — 它们对应的指向成员类型的非类型模板参数引用相同的类成员,或者既是 null 成员指针值和
— 它们对应的引用类型的非类型模板参数引用相同的外部对象或函数,并且
— 它们对应的模板模板参数引用相同的模板。

放在上下文中,这意味着同一类模板的两个实例化构成两种不同的数据类型,即使它们仅在单个非类型参数的值上不同。