Автоматическое уничтожение статического объекта - PullRequest
7 голосов
/ 22 сентября 2011

Почему C ++ не создает / уничтожает статический член типа шаблона.

Обратите внимание на следующий пример:

#include <iostream>

struct Dump {
  Dump() {
    std::cout << "CTOR" << std::endl;
  }
  ~Dump() {
    std::cout << "DTOR" << std::endl;
  }
};

template <typename T> struct X {
  static Dump dump;
};

template <typename T> Dump X<T>::dump;

struct A : X<A> {
};

int main() {
  A a;
  return 0;
}

Я бы ожидал, что при выполнении я вижу строкуCTOR с последующим DTOR.Пока нет.Что мне здесь не хватает?

Это как-то связано с dump, являющимся членом типа шаблона, но это насколько я понимаю.

Ответы [ 3 ]

5 голосов
/ 22 сентября 2011

Я нашел что-то в § 14.7.1. Неявная реализация .

1 / [...] Неявная реализация специализации шаблона класса. вызывает неявное создание экземпляров объявлений, но не определений или аргументов по умолчанию, функций-членов класса, классов-членов, перечислений членов-областей, членов-статических данных и шаблоны участников.[...]

Это продолжается во второй ноте:

2 / Если только член шаблона класса или шаблон членабыл явно создан или явно специализирован, специализация члена создается неявно, когда на специализацию ссылаются в контексте, который требует определения элемента;в частности, инициализация (и любые связанные с этим побочные эффекты) элемента статических данных не происходит, если только сам элемент статических данных не используется таким образом, который требует определенияэлемент статических данных существует.

Поэтому, если вы не используете его, его не следует создавать .Это не оптимизация, просто соответствие стандарту [n3092].

4 голосов
/ 22 сентября 2011

Члены шаблонов классов создаются только в случае необходимости; в этом случае ничто не относится к статическому члену, поэтому он не создается, даже если сам шаблон класса имеет значение.

Вы обнаружите, что размещение оператора X<A>::dump; где-нибудь приведет к созданию экземпляра члена и созданию и уничтожению объекта.

4 голосов
/ 22 сентября 2011

Не создается, если не используется. Это работает:

int main()
{
    A a;
    (void) a.dump;
}

Также исправьте ошибку компиляции:

template <typename T> Dump X<T>::dump;
...