编译的程序是否有可能不包含实例化的模板类

Is it possible that a compiled program does not contain an instantiated template class?

本文关键字:实例化 包含 程序 是否 有可能 编译      更新时间:2023-10-16

请考虑以下代码:

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

类将被实例化,但编译器不得实例化任何成员函数定义 [temp.inst]/1:

[...] 当在需要完全定义的对象类型的上下文中引用专用化时,类模板专用化是隐式实例化的 [...]

[温度]/2:

类模板专用化的隐式实例化

会导致声明的隐式实例化,但不会导致类成员函数的定义、默认参数或 noexcept-specier 的隐式实例化,[...]

编译的程序是否有可能不包含相关的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;
 }

允许编译器优化该代码。

是的,sizeof(( 不需要成员函数,因此它们很可能不会生成。所有大小的需求都是数据成员。

我构建了这段代码:

#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

我们可以看到没有生成与构造函数/析构函数关联的符号。