有大量关于何时调用普通类的静态成员的构造函数的信息。但是,我发现模板类有一些奇怪的行为。
以下程序的输出应该是什么? (请注意,我使用 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类的声明不算作模板的实例化
阿坦普尔
并导致 B 的构造函数被调用?这是标准的一部分还是 g++ 4.3 中的错误?
在类模板中,执行隐式实例化时,会根据需要实例化成员。由于代码不使用静态成员,因此它甚至没有在整个应用程序中实例化。
当您进行显式实例化时,整个类及其所有成员都会被实例化,其中包括静态成员变量,然后该变量将被初始化,您将获得预期的结果。
如果没有显式实例化,你可以做类似的事情B* p = &Atempl<int>::b_;
(或静态成员的任何其他使用)来触发实例化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)