C++模板详解(三):参数化声明详解
在前两节中(C++模板详解(一)、C++模板详解(二)),我们了解了函数模板和类模板的基本概念和使用方法。在这篇博文里,我们主要来详细地阐述一下"模板的参数声明"这个话题,并且也谈及了函数模板和类模板相结合的使用方式和一些注意事项。
一、函数模板作为普通类和模板类的成员函数
函数模板可以作为普通类和模板类的成员函数。下面的这份代码片段演示了这一点:
template<typename T1>
class List
{
public:
// 位于模板类中的成员函数模板定义:
template<typename T2>
List(const List<T2>& other);
// 错误的写法:不可以是虚函数。
template<typename T1>
virtual void func(T1&& t)
{
}
};
// #1: 在类的外部定义上面的构造函数。
template<typename T1>
template<typename T2>
List<T1>::List(const List<T2>& other)
{
//...
}
class Collection
{
// 位于普通类内部的成员函数模板定义:
template<typename T>
T* alloc()
{
//...
}
// 错误的写法:不可以是虚函数。
template<typename T>
virtual void func(T&& t)
{
}
};
这份代码展示出了很多的概念。
无论是普通类还是模板类,其中的成员函数或是模板成员函数都可以内联地定义在类中,或是定义在类的外部。在外部定义的成员函数模板可以具有多个模板参数子句:一个子句作用于该模板自身,其它子句作用于外围的类模板,其顺序是从最外围的类模板开始,依次到达内部模板。
成员函数模板不可以是虚函数。这是因为,实现虚函数需要使用一个固定大小的虚函数表,每个虚函数都对应虚函数表的一个入口。然而,成员函数模板的实例化个数,要等到整个程序都编译完成时才能确定,这就和"虚函数表的大小是固定的"发生了冲突。所以,成员函数模板不可以是虚函数。
二、模板类可以被嵌套定义在普通类或者模板类中
模板类的定义也是可以嵌套的。例如下面这份示例代码:
// 示例1:模板类可以被嵌套定义在模板类中。
template<typename T1>
class List
{
// 定义并实现。
template<typename T2>
class Node1
{
};
// 定义。
template<typename T2>
class Node2;
};
// 外部实现。
template<typename T1>
template<typename T2>
class List<T1>::Node2
{
};
// 示例2:模板类可以被嵌套定义在普通类中
class Shell
{
// 定义并实现。
template<typename T>
class Inner1
{
};
// 定义。
template<typename T>
class Inner2;
};
// 外部实现。
template<typename T>
class Shell::Inner2
{
};
类似于成员函数的类外实现,内部类的具体实现也同样可以被放到类外进行,它们的书写规则和模板成员函数几乎相同。
三、函数模板声明中的默认参数
函数模板同样可以在声明中提供缺省参数:
template<typename T>
void report(const Stack<T>& stack, int number = 10);
template<typename T>
void fill(const Array<T>& arr, const T& value = T());
由于和普通函数的缺省参数功能相似,具体的注意事项可以直接参看:C++函数详解。
C++模板详解(三):参数化声明详解的更多相关文章
- 【转】Android编译系统详解(三)——编译流程详解
原文网址:http://www.cloudchou.com/android/post-276.html 本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 1.概述 编译Androi ...
- Android 之窗口小部件详解(三) 部分转载
原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...
- 转:LoadRunner中参数化技术详解
LoadRunner中参数化技术详解 LoadRunner在录制脚本的时候,只是忠实的记录了所有从客户端发送到服务器的数据,而在进行性能测试的时候,为了更接近真实的模拟现实应用,对于某些信息需要每次提 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- 【C/C++开发】C++11 并发指南三(std::mutex 详解)
本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...
- .NET DLL 保护措施详解(三)最终效果
针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...
- [转]hibernate三种状态详解
本文来自 http://blog.sina.com.cn/u/2924525911 hibernate 三种状态详解 (2013-04-15 21:24:23) 转载▼ 分类: hibernate ...
- WebSocket安卓客户端实现详解(三)–服务端主动通知
WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...
- 多表连接的三种方式详解 hash join、merge join、 nested loop
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...
随机推荐
- 二分-F - Aggressive cows
F - Aggressive cows Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. ...
- Tomcat的使⽤
准备 1.官⽹地址:http://tomcat.apache.org下载. 2.解压文件,并放到指定路径,给该文件授权. chmod -R 755 3.启动和停止 进入到/Users/lucas/Do ...
- python 处理protobuf协议
背景:需要用django基于python3模拟一个http接口,请求是post方式,body是protobuf string,返回也是protobuf string 设计:django获取pb str ...
- DES加密算法 转
1.什么是对称密码算法 网络安全通信中要用到两类密码算法,一类是对称密码算法,另一类是非对称密码算法.对称密码算法有时又叫传统密码算法.秘密密钥算法或单密钥算法,非对称密码算法也叫公开密钥密码算法或双 ...
- ORA-00904: "I_LEVEL": invalid identifier
问题描述 ORA-00904: "I_LEVEL": invalid identifier 标示符无效
- Android 开发压缩图片
private Bitmap imageZoom(int position , Bitmap bitMap) { //图片允许最大空间 double maxSize =2 ...
- [IOI2002] 任务安排
题目链接 题意 一些不能改变顺序的任务被分成若干批,每批包含相邻的若干任务.第 $i$ 个任务单独完成所需的时间是 $T_i$.在每批任务开始前,机器需要启动时间 $S$,而完成这批任务所需的时间是各 ...
- java+selenium打开浏览器实现后台静默运行
简介:java selenium搭建无界面浏览器 PhantomJS是一个基于Webkit的"无界面"(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScri ...
- 矩阵快速幂+二分 poj3233
#include <iostream> #include <cstdio> #include <string> #include <cstring> # ...
- html表单提交给PHP然后浏览器显示出了PHP的源代码
今天学习到PHP处理网页表单提交的数据时,碰到一个巨头疼的问题,先贴上案例代码: html表单部分: <html> <head> <meta charset=" ...