繁体   English   中英

什么时候在C ++中调用模板类的静态成员的构造函数?

[英]When do constructors of static members of template classes get called in C++?

关于何时调用普通类的静态成员的构造函数,有大量信息。 但是,我看到一些关于模板类的奇怪行为。

以下程序的输出应该是什么? (注意我使用printf来避免任何静态初始化命令与std :: cout的混淆并发症。)

#include <iostream>

class B {
public:
  B(const std::string &s) { printf("Hello I am B from %s\n", s.c_str()); }
};

template<typename T>
class Atempl {
public:
  static B b_;
};

class A {
public:
  static B b_;
};

template<typename T>
B Atempl<T>::b_("Atempl");
B A::b_("A");

class C : public Atempl<int> {
};

int main(int argc, const char *argv[]) {
  return 0;
}

我认为输出应该是:

Hello I am B from A
Hello I am B from Atempl

但是使用FreeBSD 7.3上的g ++ 4.3,我得到:

Hello I am B from A

如果我添加该行

template class Atempl<int>;

一切都很好,我得到了预期的输出。 问题是,为什么类C的声明不算作模板Atempl的实例化并导致B的构造函数被调用? 这是标准的一部分还是g ++ 4.3中的错误?

在类模板中,执行隐式实例化时,会根据需要实例化成员。 由于代码不使用静态成员,因此甚至不在整个应用程序中实例化。

当您进行显式实例化时,将实例化整个类及其所有成员,并包含静态成员变量,然后对其进行初始化并获得预期结果。

如果没有显式实例化,您可以执行类似B* p = &Atempl<int>::b_; (或静态成员的任何其他用途)来触发实例化。

未指定初始化类模板模板的静态成员时。 实际上,除非你实际使用静态成员,否则不应该实例化它,因此永远不要初始化。 如果你明确地实例化了模板,你就强制实例化所有成员,这反过来会强制进行初始化(但我认为它的初始化时间仍未指定)。

它们在进程启动后和调用main()之前的某个时间由C ++运行时调用。 “常规”类和类模板实例之间没有区别。 调用构造函数的顺序是未定义的。

暂无
暂无

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

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