何时在C ++中调用模板类的静态成员的构造函数? [英] When do constructors of static members of template classes get called in C++?

查看:111
本文介绍了何时在C ++中调用模板类的静态成员的构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There is plenty of information on when constructors of static members of ordinary classes are called. However, I am seeing some strange behavior with regard to template classes.

以下程序的输出应该是什么? (请注意,我使用printf可以避免任何带有std :: cout的静态初始化订单惨败的并发症。)

What should the output of the following program be? (Note I use printf to avoid any static initialization order fiasco complications with 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时,我得到:

But with g++ 4.3 on FreeBSD 7.3 I get:

Hello I am B from A

如果我添加行

template class Atempl<int>;

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

all is well and I get the expected output. The question is, why doesn't the declaration of class C count as an instantiation of the template Atempl and cause B's constructor to be called? Is this part of the standard or a bug in g++ 4.3?

推荐答案

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

In a class template, when performing implicit instantiation, the members are instantiated on demand. Since the code does not use the static member, it is not even instantiated in the whole application.

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

When you do an explicit intantiation, the whole class and all of its members are instantiated, and that includes the static member variable, which is then initialized and you get your expected result.

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

Without the explicit instantiation you could do something like B* p = &Atempl<int>::b_; (or any other use of the static member) to trigger the instantiation.

这篇关于何时在C ++中调用模板类的静态成员的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆