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

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

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())?

4 ответа

Решение

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

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

[Temp.inst]/2:

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

Возможно ли, что скомпилированная программа не содержит соответствующего кода для 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;
 }

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

Я построил этот код:

#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

Где мы можем видеть, что никакие символы, связанные с конструктором / деструктором, не были сгенерированы.

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

Другие вопросы по тегам