考虑以下代码:
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:
[...]类模板专业化是 隐式实例化时 专业化在上下文中被引用 需要完全定义的对象类型[...]
[temp.inst] / 2:
类模板特化的隐式实例化导致了 声明的隐式实例化,而不是定义的实例化,默认参数或noexcept-specifiers 类成员函数,[...]
编译的程序是否可能不包含相关代码
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
我们可以看到没有生成与构造函数/析构函数关联的符号。