C++ 模板类';s静态变量初始化,c++;
考虑以下代码:C++ 模板类';s静态变量初始化,c++;,c++,templates,static,instantiation,linkage,C++,Templates,Static,Instantiation,Linkage,考虑以下代码: //header.h template<class T> class A { static int x; }; template<class T> int A<T>::x = 0; //source1.cpp #include "header.h" void f(){} // dummy function //main.cpp #include "header.h" int main(){} 在这种情况下,编译器错误地使用了x
//header.h
template<class T>
class A
{
static int x;
};
template<class T>
int A<T>::x = 0;
//source1.cpp
#include "header.h"
void f(){} // dummy function
//main.cpp
#include "header.h"
int main(){}
顾名思义,模板是用于不同参数的代码片段。对于模板,编译器要确保它们的方法和静态场定义是否仅链接到它们。因此,如果使用默认值创建静态字段,编译器必须提供单个内存单元(用于相同的模板参数集),即使多次包含模板类标头。不幸的是,非模板类需要自己管理 至于第二个问题,我相信标准没有说明何时需要初始化静态字段,每个编译器都可以以自己的方式实现它
A
和A
,则将有两个不同的类,因此需要初始化A::x
和A::x
A
不是模板时出错的原因
但是,当您声明模板时,在您实例化它之前,不会真正创建任何内容。由于从未实例化模板,因此从未定义静态字段,因此不会出现错误
如果在source1.cpp
(比如A
)和main.cpp
(比如A
)中有两个不同的实例化,那么一切都会很好:在source1中可以得到A::x
,在main=>中得到A::x
两个不同的变量,因为A
和A
是不同的类
在不同的编译单元中实例化同一个类的情况更为棘手。它应该会生成一个错误,但如果它生成了,您就很难在模板中声明特殊字段。因此,编译器会将其作为一个特殊情况进行处理,正如本文所述,以确保不会生成错误。编译器将自行删除重复的模板实例化。若您将模板类转换为常规类,那个么您的职责就是确保静态变量只存在一个定义(否则将出现链接器错误)。还请记住,不同类型的模板安装之间不会共享静态数据成员。使用c++11,您可以使用外部模板自行控制安装: 关于静态构件的安装点: 14.6.4.1实例化点[温度点] 1用于函数模板专用化、成员函数模板专用化或 成员函数或类模板的静态数据成员,如果专门化是隐式实例化的 因为它是从另一个模板专门化和引用它的上下文中引用的 根据模板参数,专门化的实例化点是 封闭专门化的实例化。否则,这种专门化的实例化点 紧接着引用专门化的命名空间范围声明或定义。
因此,如果您第一次在main()内使用您的类型,安装点应该在main()之后。1)类模板成员仅在需要时实例化。2) 这是一个棘手的问题。简言之,可能重复的,永远不要在头文件中实例化静态,这几乎每次都会带来麻烦。每次包含头文件时,静态都会被实例化。实际上,当您的类是模板时,编译器会处理多重定义。我的问题是,在没有使用这个类的情况下是否初始化和实例化了这个静态?这不仅是一个好的实践,还是一个需求或ODR。除非您的头没有包含在几个TU中。所以当C++标准坚持所有静态数据都应该在main之前初始化,不打扰这个情况,我是正确的吗?模板类的静态成员的构造函数肯定会在主执行之前执行。POI(安装点)是在代码构造以需要其定义的方式引用模板专门化时创建的。
class A
{
static int x;
};
int A::x = 0;