繁体   English   中英

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

[英]Is static member variable initialized in a template class if the static menber is not used?

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

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上进行的。 我也在网上测试它

#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;
}

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

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

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

C ++草案标准的相关部分来自14 模板 ,这是14.7.1 隐式实例化2段,其中说明( 强调我的 ):

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

我们还可以看到第8段说:

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

但是,如果您向第二种情况添加显式实例化 ,如下所示,您将看到2作为结果:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM