Man*_*ish 9 c++ templates constructor static-members
关于何时调用普通类的静态成员的构造函数,有大量信息.但是,我看到一些关于模板类的奇怪行为.
以下程序的输出应该是什么?(注意我使用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;
}
Run Code Online (Sandbox Code Playgroud)
我认为输出应该是:
Hello I am B from A
Hello I am B from Atempl
Run Code Online (Sandbox Code Playgroud)
但是使用FreeBSD 7.3上的g ++ 4.3,我得到:
Hello I am B from A
Run Code Online (Sandbox Code Playgroud)
如果我添加该行
template class Atempl<int>;
Run Code Online (Sandbox Code Playgroud)
一切都很好,我得到了预期的输出.问题是,为什么类C的声明不算作模板Atempl的实例化并导致B的构造函数被调用?这是标准的一部分还是g ++ 4.3中的错误?
Dav*_*eas 10
在类模板中,执行隐式实例化时,会根据需要实例化成员.由于代码不使用静态成员,因此甚至不在整个应用程序中实例化.
当您进行显式实例化时,将实例化整个类及其所有成员,并包含静态成员变量,然后对其进行初始化并获得预期结果.
如果没有显式实例化,您可以执行类似B* p = &Atempl<int>::b_;(或任何其他静态成员的使用)来触发实例化.