博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++模板实例化(1)
阅读量:4331 次
发布时间:2019-06-06

本文共 2242 字,大约阅读时间需要 7 分钟。

On-Demand实例化

当C++编译器遇到模板特化的时候,他会利用所给的实参替换对应的模板参数,从而产生该模板的特化。该过程是自动进行的。有时候也会被称为隐式实例化,或者是自动实例化。

on-demand实例化表明:在使用模板(特化)的地方编译器通常需要访问模板某些模板成员的整个定义(也就是说只有声明是不够的)考虑下面的代码。

1:  template
class C; //声明而已
2:  C
* p = 0; //这里只要声明就够了,因为这里没有new一个实例
3:   
4:  template
5:  class C{
6:  public:
7:  void f();//成员函数声明
8:  };
9:   
10:  void g(C
& c)//这里只需要类模板的声明
11:  {
12:   c.f();//这里用到了f的定义
13:  }

记住如果某个组件需要知道模板特化后的大小,或者访问该特化的成员,那么整个类模板的定义就需要位于可见区域中。因为如果编译器看不见的话,编译器就不能确定这个类中是否含有改成员函数,是否可以被访问到。

延迟实例化

当隐式实例化类模板时,同时也实例化了该模板的每个成员的声明,但并没有实例化相应的定义。

当实例化模板的时候,缺省的函数调用实参是分开考虑的。如果这个函数不使用缺省的实参而是显示的实参来进行调用的那么就不会实例化缺省实参。

然而也存在一些例外的情况,首先,如果类模板中包含了一个匿名的union,那么该模板实例化结果,union定义的成员同时被实例化。另一种情况,如果含有虚函数,虚函数的定义可能被实例化但也可能没有被实例化。这要依据具体的实现,实际上,许多实现都会被实例化虚函数这个定义,因为“实现虚函数调用机制的内部结构”要求虚函数的定义做为链接的实体存在

1:  template
2:  class Safe{
3:  };
4:  template
5:  class Danger{
6:  public:
7:  typename char Block[N];
8:  };
9:   
10:  template 
11:  class Tricky{
12:  public:
13:  virtual ~Tricky(){}
14:   
15:  void no_body_here(Safe
= 3);
16:   
17:  void inclass(){
18:  Danger
no_boom_yet;
19:  }
20:   
21:  //void error(){ Danger<0> boom; }
22:  //void unsafe(T (*p)[N]);
23:   
24:  T operator->();
25:  //virtual Safe
suspect();
26:   
27:  struct Nested{
28:  Danger
pfew;
29:  };
30:  union {
31:  int align;
32:  Safe
anonymous;
33:  };
34:  };
35:   
36:  int main()
37:  {
38:  Tricky
ok;
39:  }

再涉及到模板参数的约束时,编译器会假设该参数处于最理想的情况。例如,他会假设void no_body_here(Safe<int> = 3);不会用到隐式参数,他会假设typename char Block[N]; 中的N不是0或者是小于0的数。

如果编译main()函数,那么有哪些表达是不合法的

18:Danger
no_boom_yet; //数组元素个数不能为0
28: Danger
pfew;//数组元素个数不能为0
以上的虽然表达不合法,但是当是他们都是位于定义中,所以都没有用到所以可以被编译通过。
再来看一下备注释掉的,如果没有被注释掉的话,
25:  //virtual Safe
suspect();
因为是虚函数所以会被实例化,但是没有函数体的定义。
22: //void unsafe(T (*p)[N]);
因为会被声明所以参数中会定义元素个数为0的数组,编译不通过。
21:  //void error(){ Danger<0> boom; }
在编译期间就会产生出错,被检查到了。
 
那么18和19中的Danger
和 21中的Danger<0>中在编译时有什么区别,在没有被main中的0实例化时,
编译器会假设18和19中的Danger
中的N是合法的,而21中的Danger<0>是不合法的,这就叫延迟实例化。
 

转载于:https://www.cnblogs.com/claruarius/p/shilihua1.html

你可能感兴趣的文章
小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-05熔断降级服务异常报警通知
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-03 高级篇幅之zuul常用问题分析
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-08 断路器监控仪表参数
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-02 springcloud网关组件zuul
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-1.快速搭建SpringBoot项目,采用Eclipse...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-4.在线教育后台数据库设计...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-3.热部署在Eclipse和IDE里面的使用...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-3.在线教育站点需求分析和架构设计...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-4.后端项目分层分包及资源文件处理...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-2.快速搭建SpringBoot项目,采用IDEA...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-5.PageHelper分页插件使用
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-6.微信扫码登录回调本地域名映射工具Ngrock...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-8.用户模块开发之保存微信用户信息...
查看>>
Linux下Nginx安装
查看>>
LVM扩容之xfs文件系统
查看>>
Hbase记录-client访问zookeeper大量断开以及参数调优分析(转载)
查看>>
代码片段收集
查看>>
vue-cli3创建项目时报错
查看>>
输入1-53周,输出1-53周的开始时间和结束时间
查看>>