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

时间:2017-12-30 10:10:16

标签: c++ template-instantiation

考虑以下代码:

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 个答案:

答案 0 :(得分:12)

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

  

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

[temp.inst] / 2:

  

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

答案 1 :(得分: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;
 }

允许编译器优化该代码。

答案 2 :(得分:0)

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

答案 3 :(得分: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

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