11

考虑这段代码:

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

4 回答 4

12

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

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

[温度.inst]/2:

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

于 2017-12-30T10:22:37.567 回答
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;
 }

允许编译器优化该代码。

于 2017-12-30T10:14:04.967 回答
0

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

于 2017-12-30T10:14:10.060 回答
0

我已经建立了这个代码:

#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

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

于 2017-12-30T11:52:36.433 回答