C++学习笔记12-模板1
1. 函数模板
函数模板是一个独立于类型的函数,可作为一种方式。产生函数的特定类型版本号。
// implement strcmp-like generic compare function
// returns 0 if thevalues are equal, 1 if v1 is larger, -1 if v1 is smaller
template <typename T>
int compare(const T&v1, const T &v2)
{
if (v1 < v2)return -1;
if (v2 < v1)return 1;
return 0;
}
2. 类模板
类模板也是模板。因此必须以keywordtemplate 开头,后接模板形參表。Queue 模板接受一个名为Type 的模板类型形參。
template <class Type> class Queue {
public:
Queue (); // default constructor
Type &front (); // return element from head of Queue
const Type &front() const;
void push (const Type&); // add element to back of Queue
void pop(); // remove element from head of Queue
bool empty() const; // true if no elements in the Queue
private:
// ...
};
3. 模板形參
像函数形參一样,程序猿为模板形參选择的名字没有本质含义。在我们的样例中,将compare 的模板类型形參命名为T,但也能够将它命名为随意名字:
// equivalent template definition
template <class Glorp>
int compare(const Glorp &v1, const Glorp &v2)
{
if (v1 < v2)return -1;
if (v2 < v1)return 1;
return 0;
}
该代码定义的compare 模板与前面一样。能够给模板形參赋予的唯一含义是差别形參是类型形參还是非类型形參。
假设是类型形參。我们就知道该形參表示未知类型。假设是非类型形參。我们就知道它是一个未知值。
4. 模板形參作用域
模板形參的名字能够在声明为模板形參之后直到模板声明或定义的末尾处使用。模板形參遵循常规名字屏蔽规则。
与全局作用域中声明的对象、函数或类型同名的模板形參会屏蔽全局名字:
typedef double T;
template <class T> T calc(const T &a, const T &b)
{
// tmp has the typeof the template parameter T
// not that of the global typedef
T tmp = a;
// ...
return tmp;
}
将T 定义为double 的全局类型型别名将被名为T 的类型形參所屏蔽,因此,tmp不是double 型。相反,tmp的类型是绑定到模板形參的随意类型。使用模板形參名字的限制用作模板形參的名字不能在模板内部重用。
template <class T> T calc(const T &a, const T &b)
{
typedef double T; //error: rede clares template parameter T
T tmp = a;
// ...
return tmp;
}
这一限制还意味着模板形參的名字仅仅能在同一模板形參表中使用一次:
// error: illegalre use of template parameter name V
template <class V,class V> V calc(const V&, const V&) ;
当然,正如能够重用函数形參名字一样,模板形參的名字也能在不同模板中重用:
// ok: reuses parameter type name across different templates
template <class T> T calc (const T&, const T&) ;
template <class T> int compare(const T&, const T&) ;
5. 模板声明
像其它随意函数或类一样。对于模板能够仅仅声明而不定义。
声明必须指出函数或类是一个模板:
// declares compare but does not define it
template <class T> int compare(const T&, const T&) ;
同一模板的声明和定义中。模板形參的名字不必同样。
// all three uses of calc refer to the same function template
// forward declarations of the template
template <class T> T calc(const T&, const T&) ;
template <class U> U calc(const U&, const U&) ;
// actual definitionof the template
template <class Type>
Type calc(const Type& a, const Type& b) { /* ... */ }
每一个模板类型形參前面必须带上keyword class 或 typename,每一个非类型形參前面必须带上类型名字,省略keyword或类型说明符是错误的:
// error: must precede U by either typename or class
template <typename T, U> T calc (const T&, const U&) ;
6. typename 与 class 的差别
在函数模板形參表中,keywordtypename 和class 具有同样含义,能够互换使用。两个keyword都能够在同一模板形參表中使用:
// ok: no distinction between typename and class in template parameter list
template <typename T, class U> T calc (const T&, const U&);
使用keywordtypename 取代keywordclass 指定模板类型形參或许更为直观。毕竟。能够使用内置类型(非类类型)作为实际的类型形參,并且,typename更清楚地指明后面的名字是一个类型名。可是,keywordtypename 是作为标准C++ 的组成部分增加到C++ 中的,因此旧的程序更有可能仅仅用keywordclass。
7. 编写泛型代码的两个重要原则:
• 模板的形參是const 引用。
• 函数体中的測试仅仅用< 比較。
8. 类模板形參是必需的
想要使用类模板,就必须显式指定模板实參:
Queue qs; // error:which template instantiation?
类模板不定义类型,仅仅有特定的实例才定义了类型。特定的实例化是通过提供模板实參与每一个模板形參匹配而定义的。
模板实參在用逗号分隔并用尖括号括住的列表中指定:
Queue<int> qi; // ok: defines Queue that holds ints
Queue<string>qs; // ok: defines Queue that holds strings
9. 类型形參的实參的受限转换
考虑以下的compare 调用:
short s1, s2;
int i1, i2;
compare(i1, i2); // ok: instantiate compare(int, int)
compare(s1, s2); // ok: instantiate compare(short, short)
一般而论。不会转换实參以匹配已有的实例化,相反,会产生新的实例。除了产生新的实例化之外,编译器仅仅会运行两种转换:
•const 转换:接受const 引用或const 指针的函数能够分别用非const对象的引用或指针来调用,无须产生新的实例化。假设函数接受非引用类型,形參类型实參都忽略const,即。不管传递const 或非const 对象给接受非引用类型的函数,都使用同样的实例化。
• 数组或函数到指针的转换:假设模板形參不是引用类型。则对数组或函数类型的实參应用常规指针转换。数组实參将当作指向其第一个元素的指针,函数实參当作指向函数类型的指针。
比如,考虑对函数fobj 和fref 的调用。
fobj函数复制它的形參,而fref的形參是引用:
template <typename T> T fobj(T, T); // arguments are copied
template <typename T> T fref(const T&,const T&); // reference arguments
string s1("avalue");
const strings2("another value");
fobj(s1, s2); // ok:calls f(string, string), const is ignored
fref(s1, s2); // ok: non const object s1 converted to const reference
int a[10], b[42];
fobj(a, b); // ok:calls f(int*, int*)
fref(a, b); // error:array types don't match; arguments aren't converted to pointers
第一种情况下。传递string 对象和const string 对象作为实參,即使这些类型不全然匹配,两个调用也都是合法的。
在fobj 的调用中,实參被复制,因此原来的对象是否为const 无关紧要。在fref 的调用中,形參类型是const引用,对引用形參而言,转换为const 是能够接受的转换,所以这个调用也正确。
在另外一种情况中,将传递不同长度的数组实參。fobj的调用中。数组不同无关紧要,两个数组都转换为指针,fobj的模板形參类型是int*。可是。fref的调用是非法的,当形參为引用时数组不能转换为指针,a和b 的类型不匹配,所以调用将出错。
10. 类型转换的限制仅仅适用于类型为模板形參的那些实參。
C++学习笔记12-模板1的更多相关文章
- OpenCV 学习笔记(模板匹配)
		OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够 ... 
- Ext.Net学习笔记12:Ext.Net GridPanel Filter用法
		Ext.Net学习笔记12:Ext.Net GridPanel Filter用法 Ext.Net GridPanel的用法在上一篇中已经介绍过,这篇笔记讲介绍Filter的用法. Filter是用来过 ... 
- SQL反模式学习笔记12  存储图片或其他多媒体大文件
		目标:存储图片或其他多媒体大文件 反模式:图片存储在数据库外的文件系统中,数据库表中存储文件的对应的路径和名称. 缺点: 1.文件不支持Delete操作.使用SQL语句删除一条记录时,对应的文 ... 
- Python Flask学习笔记之模板
		Python Flask学习笔记之模板 Jinja2模板引擎 默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板.Flask提供的render_template函数把Jinja ... 
- golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题
		golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题 今天测试了重新建一个项目生成新的表,然后复制到旧的项目 ... 
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
		Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ... 
- Python3+Selenium3+webdriver学习笔记12(js操作应用:滚动条 日历 内嵌div)
		#!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记12(js操作应用:滚动条 日历 内嵌div)'''from ... 
- springmvc学习笔记(12)-springmvc注解开发之包装类型參数绑定
		springmvc学习笔记(12)-springmvc注解开发之包装类型參数绑定 标签: springmvc springmvc学习笔记12-springmvc注解开发之包装类型參数绑定 需求 实现方 ... 
- 并发编程学习笔记(12)----Fork/Join框架
		1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ... 
- matlab学习笔记12单元数组和元胞数组 cell,celldisp,iscell,isa,deal,cellfun,num2cell,size
		一起来学matlab-matlab学习笔记12 12_1 单元数组和元胞数组 cell array --cell,celldisp,iscell,isa,deal,cellfun,num2cell,s ... 
随机推荐
- [转]Android使用Application总结
			目录(?)[+] Application 配置全局Context 第一步.写一个全局的单例模式的MyApplication继承自Application 覆盖onCreate ,在这个方法里 ... 
- Educational Codeforces Round 13 D. Iterated Linear Function 水题
			D. Iterated Linear Function 题目连接: http://www.codeforces.com/contest/678/problem/D Description Consid ... 
- 如何让浮动的元素换行??css
			当你想要做成这种布局效果的时候 紫色框里面的内容那样 它是一个列表 li元素是块级元素 默认大小是父元素ul的宽 并且换行 如果li没有背景的话那就不用管了 可是问题来了它不但有背景 而且是根据文字 ... 
- SQL2008″Unable to read the list of previously registered servers on this system”
			打开SQL2008,弹出”Unable to read the list of previously registered servers on this system”错误, 微软官方的解决方法:h ... 
- Hello World on Impala
			Cloudera Impala 官方教程 <Impala Tutorial>,解说了Impala一些基本操作,但操作步骤前后缺少连贯性,本文节W选<Impala Tutorial&g ... 
- 相比xib 使用代码编排view 的一个明显的好处就是可以更好地重复使用已有代码,减少代码冗余。
			相比xib 使用代码编排view 的一个明显的好处就是可以更好地重复使用已有代码,减少代码冗余. 
- 什么是软件project?
			Normal 0 7.8 pt 0 2 false false false MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNo ... 
- [MAC OS]   解压Assets.car获取资源图片
			reference to : http://www.jianshu.com/p/a5dd75102467 今天想获取APP的资源,但是查看xxx.app文件夹里面,缺少了大部分资源.在文件夹里面发现 ... 
- MapReduce模式MapReduce patterns
			After having modified and run a job in the last post, we can now examine which are the most frequent ... 
- VS2010+OpenCV2.4.3配置
			VS2010+OpenCV2.4.3配置: 环境变量path: D:\openCV2.4.3\opencv\build\x86\vc10\bin 项目-属性-VC++目录:(vs2008中,工具- ... 
