为什么C ++不创建/销毁模板类型的静态成员。
请注意以下示例:
#include <iostream>
struct Dump {
Dump() {
std::cout << "CTOR" << std::endl;
}
~Dump() {
std::cout << "DTOR" << std::endl;
}
};
template <typename T> struct X {
static Dump dump;
};
template <typename T> Dump X<T>::dump;
struct A : X<A> {
};
int main() {
A a;
return 0;
}
我原本以为在执行时我会看到字符串CTOR
后跟DTOR
。虽然我没有。我在这里缺少什么?
它与dump
作为模板类型的成员有关,但这就是我得到的。
答案 0 :(得分:5)
我在§14.7.1隐式实例化中找到了一些东西。
1 / [...]类模板特化的隐式实例化导致声明的隐式实例化,但不是类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板的定义或缺省参数。 [...]
在第二个注释中继续:
2 / 除非已明确实例化或明确专门化类模板或成员模板的成员,否则在需要使用特定化的上下文中引用特化时,将隐式实例化成员的特化。成员定义存在;特别是,静态数据成员的初始化(以及任何相关的副作用)除非静态数据成员本身使用,否则不会发生需要定义的方式静态数据成员的存在。
因此,除非您使用它,否则不应该实例化。这不是优化,只是标准[n3092]一致性。
答案 1 :(得分:4)
除非使用,否则不会实例化。这有效:
int main()
{
A a;
(void) a.dump;
}
另外,修复编译错误:
template <typename T> Dump X<T>::dump;
答案 2 :(得分:4)
只有在需要时才会实例化类模板的成员;在这种情况下,没有任何东西引用静态成员,所以它没有实例化,即使类模板本身是。
您会发现将语句X<A>::dump;
放在某处将导致成员被实例化并创建和销毁对象。