考虑这段代码:
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()
)的相关代码?
考虑这段代码:
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:
[...] 当在需要完全定义的对象类型的上下文中引用特化时,类模板特化被隐式实例化[...]
[温度.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;
}
允许编译器优化该代码。
是的, sizeof() 不需要成员函数,因此很可能不会生成它们。所有 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
我们可以看到没有生成与构造函数/析构函数关联的符号。