模板的静态成员
Static member of template
这里有一个类似的问题,但它与带有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
类型的静态成员s
,X<char*>
有一个char*
类型的静态成员s
。
上面标准给出的示例提到了类型参数,但第 14.7/6 节是模板一般讨论的一部分。更广泛的上下文清楚地表明,这适用于使用非类型参数(或类型、非类型和模板参数的组合(的模板。
还有一个关于模板实例化的类型等效性的部分,它解释了在什么情况下使用非类型参数的模板实例化被认为是相等的(相关部分由我强调(:
(§14/1( 两个模板 ID 引用同一个类或函数,如果
— 它们的模板名称、运算符函数 ID 或文字运算符 ID 引用相同的模板和
— 它们对应的类型模板参数是相同的类型,并且
— 它们对应的整型或枚举型非类型模板参数具有相同的值和
— 它们对应的指针类型的非类型模板参数引用相同的外部对象或函数,或者既是空指针值又
是空指针值 — 它们对应的指向成员类型的非类型模板参数引用相同的类成员,或者既是 null 成员指针值和
— 它们对应的引用类型的非类型模板参数引用相同的外部对象或函数,并且
— 它们对应的模板模板参数引用相同的模板。
放在上下文中,这意味着同一类模板的两个实例化构成两种不同的数据类型,即使它们仅在单个非类型参数的值上不同。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 如何在C++中使用非静态成员函数作为回调函数
- (C++)为什么静态成员可以在初始化之前使用
- 类的全局对象和静态成员
- 在作为静态成员包含在另一个类中的类的构造函数中使用 cout
- 模板化类中静态成员的延迟初始化
- 使用静态成员声明类时遇到问题
- C++:是否可以使用非静态成员变量模板?
- 静态成员函数使用相同的名称时出现模板类型名称错误
- 如何在复杂继承中访问静态成员变量
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 如何在友元函数中使用静态成员而不添加前缀 [类名]::
- C++构造函数和静态成员
- 为什么传递非静态成员函数会导致编译错误?
- 非静态成员失败的线程调用函数
- 静态成员变量不会由 gettext 转换
- decltype:使用指针访问类的静态成员
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 非静态成员函数的 decltype 格式不正确吗?
- 如何在C++中定义静态成员结构