3

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

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。 regist() 不被称为 abd 静态成员未初始化。我的测试是在 VC110 编译器上进行的。而且我也在网上测试

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

2 回答 2

3

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

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

我们还可以看到第8段:

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

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

template<> bool A<int>::d = [](){regist<A<int>>(); return true;}();
于 2013-10-13T03:41:22.253 回答
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 和 running 也存在。—结束示例] —结束注释]

这是确认您的怀疑的标准的相关部分。

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

我认为我以粗体突出显示的两个部分可以解决您的问题。很明显,这种行为的原因是,如果没有给出明确的特化,编译器就无法决定代码应该执行多少次(无限可能的类型)

于 2013-10-13T02:59:26.597 回答