C++ 模板静态成员构造函数未被调用

标签 c++ templates visual-c++ static generic-programming

我有两个具有静态成员实例的类的测试用例。第一个使用非模板化样本,而第二个依赖于通用对象类型。

困境很简单:静态成员的构造函数在主函数之前被调用(理应如此),但仅限于特定的对象类型。泛型类型不表现出相同的行为。事实上,构造函数根本没有被编译。编译器似乎决定完全忽略它作为(不完全合理)优化的一种手段。

我想知道发生了什么以及可以做些什么来让它以最优雅的方式工作。我认为明显的答案是:在代码中的某处使用该静态成员。我不想这样做,因为除了在其构造函数中执行一些“工作”之外,特定类型的情况无需使用该静态成员即可工作。

代码示例:

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

Full live example .

关于C++ 模板静态成员构造函数未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21900694/

相关文章:

c++ - 在 g++ (mingw) 编译的应用程序中使用用 visual studio 编译的库

C++ 多线程 - 如何处理对共享变量的写入

c++ - 有没有办法完全禁用 gdb 输出?

c++ - Working with a secondary datastructure//数据结构的建议

php - 使用 Zend_View 丢失换行符的文本电子邮件模板

c++ - 在预处理器指令中使用模板参数?

c++ - 具有非模板基的模板化类给我一个 LNK2005 错误

c++ - 将 Visual C++ 6 项目升级到 Visual Studio 2008 时出现的破译错误

c++ - 迭代 vector 时扩展 vector

c++ - 使用 C++ 代码的小型计算器