Возможно ли, что скомпилированная программа не содержит экземпляр класса шаблонов?

Рассмотрим этот код:

template <typename T>
class A {
    T x;
    // A bunch of functions
};

std::size_t s = sizeof(A<double>);

Предположим, что оператор sizeof является единственным местом, где требуется создание экземпляра A<double>. Возможно ли, что скомпилированная программа не содержит соответствующий код для A<double> (например, A<double>::~A())?

Ответ 1

Класс будет создан, но компилятор не должен создавать экземпляр любого определения функции-члена, [temp.inst]/1:

[...] специализация шаблона класса неявно создается, когда специализация ссылается в контексте, который требует полностью определенного типа объекта [...]

[temp.inst]/2:

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

Ответ 2

Возможно ли, что скомпилированная программа не содержит соответствующий код для A<double> (например, A<double>::~A())?

Конечно, это возможно.

std::size_t s = sizeof(A<double>);

- это просто операция времени компиляции и не нуждается в экземпляре времени выполнения A<double>, поэтому нет необходимости в конструкторах, деструкторах или другом соответствующем коде.


Даже если бы были явные экземпляры кода функции шаблона, например, следующие

 if(sizeof(A<double>) <= 4) {
      A<double> a; // Instantiation of constructor and destructor
      a.x = 3.5;
 }

компилятору разрешено оптимизировать этот код.

Ответ 3

Да, sizeof() не нуждается в функциях-членах, и поэтому они не могут быть сгенерированы. Все потребности sizeof являются членами данных.

Ответ 4

Я создал этот код:

#include <cstddef>


template <typename T>
class A {
    T x;
    // A bunch of functions
};


int main(const int argc, const char* argv[])
{
    std::size_t s = sizeof(A<double>);
}

И запуск objdump Я получаю этот вывод:

$ objdump -t a.out 

a.out:  file format Mach-O 64-bit x86-64

SYMBOL TABLE:
0000000100000000 g     F __TEXT,__text  __mh_execute_header
0000000100000f90 g     F __TEXT,__text  _main
0000000000000000         *UND*  dyld_stub_binder

Если мы увидим, что никаких символов, связанных с конструктором/деструктором, не было создано.