如果不使用静态成员,是否在模板类中初始化静态成员变量?

时间:2013-10-13 02:53:39

标签: c++ templates static-members class-template

如果未使用静态成员,是否在模板类中初始化了静态成员变量?我用它来注册类型。

template<class T>
class A
{
    static bool d;
};

template<class T> bool A<T>::d = [](){regist<A<T>>(); return true;}();

int main()
{
   A<int> a;
   return 0;
}

我找到了一种方法来测试它。它打印1以外的2.注册表()不会被称为abd静态成员未初始化。我的测试是在VC110 compilter上进行的。我也测试了它online

#include <iostream>
using namespace std;

int i = 1;

template<class T>
void regist()
{
    ++i;
}

template<class T>
class A
{
    static bool d;
};

template<class T> bool A<T>::d = [](){regist<A<T>>(); return true;}();

int main()
{
    A<int> a;
    cout << i << endl;
    return 0;
}

2 个答案:

答案 0 :(得分:2)

是的,它已初始化运行此示例程序,但仅限于它被强制存在。

template <class T>                                                                 
struct A                                                                           
{                                                                                  
    static int b;                                                                  
};                                                                                 
template <class T> int A<T>::b = 10;                                               
#include <iostream>                                                                
using namespace std;                                                               
int main() {                                                                       
    cout << A<int>::b << endl;                                                     
    return 0;                                                                      
}   

我相信标准的引用可能会澄清任何疑问

  

[注意:一旦定义了静态数据成员,即使没有创建其类的对象,它也存在。 [示例:在上面的示例中,即使程序没有创建类进程的对象,run_chain也会运行。 - 结束例子] - 结束注释]

这是该标准的相关部分,证实了您的怀疑。

  

除非已明确实例化(14.7.2)或显式专用(14.7.3)类模板特化,否则在需要完全定义的对象类型的上下文中引用特化时,将隐式实例化类模板特化。当类类型的完整性影响程序的语义时。类模板特化的隐式实例化会导致类成员函数,成员类,静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化。它会导致成员匿名联合的定义的隐式实例化。除非已经显式实例化或明确专门化了类模板或成员模板的成员,否则在需要成员定义存在的上下文中引用特化时,将隐式地实现成员的特化;特别是,除非静态数据成员本身以需要静态数据成员定义存在的方式使用,否则不会发生静态数据成员的初始化(以及任何相关的副作用) 。

我用粗体突出显示的两个部分我想清楚你的问题。显然,这种行为的原因是如果没有给出明确的特化,编译器就无法决定代码执行的次数(无限可能的类型)

答案 1 :(得分:2)

C++ draft standard的相关部分位于14 模板下,14.7.1 隐式实例化 2 < / em>其中说(强调我的):

  

除非已经显式实例化或明确专门化了类模板或成员模板的成员,否则在需要成员定义存在的上下文中引用特化时,将隐式实例化成员的特化;特别是,除非静态数据成员本身以需要静态数据成员定义存在的方式使用,否则不会发生静态数据成员的初始化(以及任何相关的副作用)。

我们还可以看到段落 8 ,其中包含:

  

类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化。

但是,如果您将显式实例化添加到第二个案例中,您将看到2作为结果:

template<> bool A<int>::d = [](){regist<A<int>>(); return true;}();