我有两个具有静态成员实例的类的测试用例。第一个使用非模板化样本,而第二个依赖于通用对象类型。
困境很简单:静态成员的构造函数在主函数之前被调用(理应如此),但仅限于特定的对象类型。泛型类型不表现出相同的行为。事实上,构造函数根本没有被编译。编译器似乎决定完全忽略它作为(不完全合理)优化的一种手段。
我想知道发生了什么以及可以做些什么来让它以最优雅的方式工作。我认为明显的答案是:在代码中的某处使用该静态成员。我不想这样做,因为除了在其构造函数中执行一些“工作”之外,特定类型的情况无需使用该静态成员即可工作。
代码示例:
//////////////////////////////////////////////
// Specific case
//////////////////////////////////////////////
class CPassive
{
public:
CPassive()
{
printf(" passively called ");
}
};
class CActive
{
private:
static CPassive ms_passive;
};
CPassive CActive::ms_passive;
///////////////////////////////////////////////////////////
// GENERIC TYPES
///////////////////////////////////////////////////////////
class CSample
{
public:
CSample()
{
printf("sample ");
}
};
template <typename T>
class CGenericPassive
{
public:
CGenericPassive()
{
T sample;
printf(" generic passive .. ");
}
private:
};
template <typename T>
class CGenericActive
{
private:
static CGenericPassive<T> ms_passive;
};
template<typename T>
CGenericPassive<T> CGenericActive<T>::ms_passive;
int main(int argc, char** argv)
{
CActive activeExample;// instantiates the static member
CGenericActive<CSample> activeExample; // obliterates the static from the class def.
}
最佳答案
您想要实例化的每个类模板的每个(非虚拟)成员都需要从非模板代码中直接或间接引用。实例化类本身是不够的。
这受标准 14.7.1/2 管辖:
Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
在您的情况下,从 CGenericActive
构造函数引用成员就足够了(显然您需要编写此构造函数),如下所示:
CGenericActive()
{
// just reference it so it gets instantiated
(void)ms_passive;
}
关于C++ 模板静态成员构造函数未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21900694/