C++模板实例化(1)
On-Demand实例化
当C++编译器遇到模板特化的时候,他会利用所给的实参替换对应的模板参数,从而产生该模板的特化。该过程是自动进行的。有时候也会被称为隐式实例化,或者是自动实例化。
on-demand实例化表明:在使用模板(特化)的地方编译器通常需要访问模板某些模板成员的整个定义(也就是说只有声明是不够的)考虑下面的代码。
1: template<typename T> class C; //声明而已
2: C<int >* p = 0; //这里只要声明就够了,因为这里没有new一个实例
3:
4: template<typename T>
5: class C{
6: public:
7: void f();//成员函数声明
8: };
9:
10: void g(C<int>& c)//这里只需要类模板的声明
11: {
12: c.f();//这里用到了f的定义
13: }
记住如果某个组件需要知道模板特化后的大小,或者访问该特化的成员,那么整个类模板的定义就需要位于可见区域中。因为如果编译器看不见的话,编译器就不能确定这个类中是否含有改成员函数,是否可以被访问到。
延迟实例化
当隐式实例化类模板时,同时也实例化了该模板的每个成员的声明,但并没有实例化相应的定义。
当实例化模板的时候,缺省的函数调用实参是分开考虑的。如果这个函数不使用缺省的实参而是显示的实参来进行调用的那么就不会实例化缺省实参。
然而也存在一些例外的情况,首先,如果类模板中包含了一个匿名的union,那么该模板实例化结果,union定义的成员同时被实例化。另一种情况,如果含有虚函数,虚函数的定义可能被实例化但也可能没有被实例化。这要依据具体的实现,实际上,许多实现都会被实例化虚函数这个定义,因为“实现虚函数调用机制的内部结构”要求虚函数的定义做为链接的实体存在。
1: template<typename T>
2: class Safe{
3: };
4: template<int N>
5: class Danger{
6: public:
7: typename char Block[N];
8: };
9:
10: template <typename T, int N>
11: class Tricky{
12: public:
13: virtual ~Tricky(){}
14:
15: void no_body_here(Safe<int> = 3);
16:
17: void inclass(){
18: Danger<N> no_boom_yet;
19: }
20:
21: //void error(){ Danger<0> boom; }
22: //void unsafe(T (*p)[N]);
23:
24: T operator->();
25: //virtual Safe<T> suspect();
26:
27: struct Nested{
28: Danger<N> pfew;
29: };
30: union {
31: int align;
32: Safe<T>anonymous;
33: };
34: };
35:
36: int main()
37: {
38: Tricky<int, 0> ok;
39: }
再涉及到模板参数的约束时,编译器会假设该参数处于最理想的情况。例如,他会假设void no_body_here(Safe<int> = 3);不会用到隐式参数,他会假设typename char Block[N]; 中的N不是0或者是小于0的数。
如果编译main()函数,那么有哪些表达是不合法的
18:Danger<N> no_boom_yet; //数组元素个数不能为0
28: Danger<N> pfew;//数组元素个数不能为0
以上的虽然表达不合法,但是当是他们都是位于定义中,所以都没有用到所以可以被编译通过。
再来看一下备注释掉的,如果没有被注释掉的话,
25: //virtual Safe<T> suspect();
因为是虚函数所以会被实例化,但是没有函数体的定义。
22: //void unsafe(T (*p)[N]);
因为会被声明所以参数中会定义元素个数为0的数组,编译不通过。
21: //void error(){ Danger<0> boom; }
在编译期间就会产生出错,被检查到了。
那么18和19中的Danger<N> 和 21中的Danger<0>中在编译时有什么区别,在没有被main中的0实例化时,
编译器会假设18和19中的Danger<N>中的N是合法的,而21中的Danger<0>是不合法的,这就叫延迟实例化。
C++模板实例化(1)的更多相关文章
- C++模板实例化
深入理解C++中第七章提到模板实例化参数的选择:函数的决议结果只和函数参数有关和返回值无关.记录一下. 测试程序如下: #include <iostream> using namespac ...
- c++模板实例化的一个例子
以下是c++模板实例化的一个例子,虽然ObjectList::clear()里面调用的test()函数是没有定义的,但是以下代码能够编译通过,可见ObjectList::clear()未编译: tem ...
- SQL模板和模板实例化
需求:需要得出一个数据源DataTable,我已知SQL和HttpRequest如何,通过SQL模板的方式去实例化匹配HttpRequest中的参数实例化为查询SQL,最后返回DataTable 1. ...
- C++模板之函数模板实例化和具体化
模板声明 template<typename/class T>, typename比class最近后添加到C++标准. 常规模板,具体化模板,非模板函数的优先调用顺序. 非模板函数(普通 ...
- C++ Primer 学习笔记_77_模板与泛型编程 --实例化
模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实 ...
- 如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类
本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-t ...
- C++ template —— 实例化和模板实参演绎(四)
本篇讲解实例化和模板实参演绎-------------------------------------------------------------------------------------- ...
- C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解
模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始 ...
- 使用 c++ 模板显示实例化解决模板函数声明与实现分离的问题
问题背景 开始正文之前,做一些背景铺垫,方便读者了解我的工程需求.我的项目是一个客户端消息分发中心,在连接上消息后台后,后台会不定时的给我推送一些消息,我再将它们转发给本机的其它桌面产品去做显示.后台 ...
随机推荐
- Cocos2d-x 程序是如何开始运行与结束的
题记:对于技术,我们大可不必挖得那么深,但一定要具备可以挖得很深的能力 问题的由来 怎么样使用 Cocos2d-x 快速开发游戏,方法很简单,你可以看看其自带的例程,或者从网上搜索教程,运行起 ...
- Web service是什么?(转)
我认为,下一代互联网软件将建立在Web service(也就是"云")的基础上. 我把学习笔记和学习心得,放到网志上,欢迎指正. 今天先写一个最基本的问题,Web service到 ...
- Linux内存管理学习笔记 转
https://yq.aliyun.com/articles/11192?spm=0.0.0.0.hq1MsD 随着要维护的服务器增多,遇到的各种稀奇古怪的问题也会增多,要想彻底解决这些“小”问题往往 ...
- ip协议的数据分片备忘
总结: 不仅tcp协议能对数据段进行分割,ip协议也具备这个功能,之所以会这样是两者都受到底层MTU的限制(虽说tcp是根据MSS限制来分割数据包,由于MTU=tcp包头+ip包头+MSS,所以其实也 ...
- careercup-高等难度 18.2
18.2 编写一个方法,洗一副牌.要求做到完美洗牌,换言之,这幅牌52!种排列组合出现的概率相同.假设给定一个完美的随机发生器. 解法:假定有个数组,含有n个元素,类似如下: [1][2][3][4] ...
- 在 linux(ubuntu) 下 安装 LibSVM
原文:http://blog.csdn.net/rav009/article/details/12995095 在安装LibSVM前需要先装 python 和 gnuplot linux 一般都自带了 ...
- STC51系列单片机免掉电下载(热启动下载)
相信喜欢单片机的朋友都用过STC的单片机,用过STC单片机的朋友都有这种感受:实惠.易用.功能强大!就是每次下载都要冷启动特别恶心,相信很多朋友的开发板上的电源键都按烂了. 其实STC单片机可以不用免 ...
- 代码片段 - Golang 创建 .tar.gz 压缩包
Golang创建 .tar.gz 压缩包 tar 包实现了文件的打包功能,可以将多个文件或目录存储到单一的 .tar 文件中,tar 本身不具有压缩功能,只能打包文件或目录: import " ...
- Nginx的一些基本功能极速入门
本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理. 1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片 ...
- layer.js,,,分享一个好用的弹出层
基本属性: <!DOCTYPE html> <html> <head> <head> <meta content="text/html; ...