文章目录

  • 1.函数模板
  • 2.类模板
    • 2.1类模板的基本使用
    • 2.2类模板中的友元
  • 3.模板默认参数
    • 3.1模板函数的默认参数
    • 3.2类模板默认参数
  • 4.成员模板
    • 4.1普通类的成员模板
    • 4.2模板类的成员模板
    • 4.3函数模板与类型转换
  • 5.函数模板的显示指定

C++中提供模板使得函数或者类可以可得极大的扩展,比入我们使用的 vector或者vector 就是基于模板的实现的,以下是关于模板的笔记。

1.函数模板

函数模板使得我们的函数可以只需要一次声名和实现就可以传入不同类型的参数调用函数。声名和实现函数时都需要加上关键字template<typename T>在函数面前.

template<typename T>
int cmp(const T& v1,const T& v2) {if(v1<v2) return -1;if(v2<v1) return 1;else return 0;
}

当假如调用函数cmp(5,20)则上述的函数中的T将会被替换为int ,如果我们调用函数 cmp("aaa","bbb");函数模板中的T将会被替换为string,只有当函数调用时我们的函数才会进行实例化。上述的typename可以替换为class,两者等价。函数模板可以调用自定义的类,但是自定义的类必须实现函数中用到的运算符,比如cmp ,如果传入某个类作为参数,则该类必须实现 < 运算符的重载。函数模板可以有多个类型参数,比如template<typename T1,typename T2>

2.类模板

2.1类模板的基本使用

类模板和函数模板类似,需要在定义类的前面加上关键字template<typename T1,typename T2>, 我们用的vector等容器也是基于类模板实现的,在对类进行实现时,我们可以将T1,T2 等看成是类的参数,在类中可以直接使用。下面给出一个简单模板类的例子,用模板类实现栈的基本操作:

template<typename T> class Mystack {public://默认构造函数Mystack() :StackCapacity(0),p(nullptr),top(-1) {}//构造函数,需要指定栈的容量Mystack(const int size):StackCapacity(size),p(new T[StackCapacity]),top(-1) {}//拷贝构造函数Mystack(const Mystack<T>& s) : StackCapacity(s.StackCapacity),top(s.top) {//赋值栈中的元素p.reset(new T[StackCapacity]);for (int i = 0; i < s.top + 1; i++)p[i] = s.p[i];}//赋值运算符重载Mystack<T>& operator = (const Mystack<T>& s){Mystack<T> temp(s);swap(temp);return *this;}//析构函数~Mystack(){}//交换两个对象void swap(Mystack<T> & s1){std::swap(s1.StackCapacity,StackCapacity);std::swap(s1.top,top);p.swap(s1.p);}//入栈成功返回true,失败返回falsebool push(const T t) {if (top < (StackCapacity - 1)) {top++;p[top] = t;return true;}else {return false;}};//pair::first为出栈的值,pair::second表示是否出栈成功pair<T, bool> pop() {if (top > -1) {top--;return { p[top + 1],true };}else {return pair<T, bool>();}};//获取栈顶元素,但是栈顶指针不动T peek(){if (top > -1) {return p[top];};}//栈为空返回truebool is_empty() {if (top == -1)return true;elsereturn false;};//返回当前栈的大小int size() {return (top+1);};
private:int StackCapacity;unique_ptr<T[]> p;//执行栈的智能指针int top;//表示栈顶的指针
};

对于上述的Mystack,我们使用时应该这样使用。

Mystack<string>stack(20);//容量为20的存储字符串的栈。
Mystack<int>stack(20);//容量为20的int类型的栈。

这时编译器便会将上述案例中的T替换为string ,这是对象stack 就是一个容量为20的存储字符串的栈。

类外成员函数的实现
在类为实现模板类的成员函数时应该在成员函数之前加上关键字template,例如上述的压栈操作的类外实现如下:

template<typename T>
bool Mystack<T>::push(const T t)
{if (top < (*StackSize - 1)) {top++;p[top] = t;return true;}else {return false;}
}

成员函数前必须加上和类模板一样的声名template<typename T>,而且类的名称要写为Mystack<T>。当在类外实现成员函数时,<T>不能省略。

2.2类模板中的友元

友元函数或者友元类可以访问类的私有变量,在模板中的友元声名有很多种情况。
一对一

template<typename> class A;
template<typename T> class B
{friend class A<T>;//A<T>为B<T>的友元类;
};

上述B类将A类声名为友元类,当且仅当A类和B类的接受的类型相同时成立。如下:

B<int> b_int;//所有的A<int>均可以访问对象b_int的私有成员。
B<string> b_string;//所有的A<string>均可以访问对象b_string的私有成员。

模板自己的类型参数为友元
如果我们要将类型参数声名为自己的友元类,则该如下声名:

template<typename T> class B
{friend T;..........
};

多对多
如果我们要将模板的所有类型都声名为友元类型,则可以在模板类的内部进行声名,但是两个模板类的参数名称不能相等。

template<typename T> class B
{template<typename X> friend class A;...........
};

A的所有实例对象都声名为B的友元类。此处的A可以为非模板类。

3.模板默认参数

如同我们的函数有默认参数一样,我们的模板也有默认参数。模板的默认参数的使用方式和函数的默认参数使用差不多。

3.1模板函数的默认参数

对于函数模板的默认参数,一般我们需要同时指定模板的默认参数和函数的的默认参数(当模板参数没有最为函数参数出现时一般不用指定函数的默认参数)。例子:

template<typename T1,typename T2=int>
void print(T1 v1,T2 v2=0)
{//模板默认参数作为函数的参数,函数的参数一般需要指定默认值cout << v1 << " " <<v2<< endl;
}template<typename T1,typename T2=int>
void print(T1 v1)
{T2 v2 = 10;//模板的默认参数不作为函数参数。cout <<v1<<" "<<v2<< endl;
}

3.2类模板默认参数

template<typename T1,typename T2=int>
class test {public:void print(T1 v1, T2 v2=0) {cout << v1 << " " << v2 <<endl;};
};test<string> t1;//声明可以省略类型说明符T2
t1.print("hello");//输出为“hello 0”

对于只有一个参数,且该参数有默认值的模板而言,我们在使用时不能将“<>”省略。

template<typename T=int> class test;
//声明实例对象时应该保留“<>”
test<> t1;//参数类型缺省时使用默认值。

4.成员模板

4.1普通类的成员模板

函数模板可以作为类的成员函数,其作为普通类的成员函数的使用方式和函数模板没有区别,下面是一个删除器的例子:

class Deleter {public:template<typename T>void operator()(T *t) const{cout << "delete successfully"<< endl;delete t;}
};int* p = new int(10);
Deleter del;
del(p);

4.2模板类的成员模板

模板类的成员函数为函数模板时,其使用方式和普通的函数模板并没有太大区别,只是命名不能有太大冲突,以及在类外实现函数是需要同时指明类和函数的模板声明。

template<typename T1>
class Deleter {public:template<typename T>void operator()(T* t) const{cout << "delete successfully" << endl;delete t;}void show(T1 t){cout << t << endl;}
};int* p = new int(10);
Deleter<string> del;del.show("this is a test");del(p);

如果在类外实现模板函数则其应该同时加上类模板和函数模板的声明。

template<typename T1>
template<typename T>
void fun()
{.......
}

4.3函数模板与类型转换

将实参传递给模板参数时,能够自动应用的类型转换只有const转换和数组或者函数到指针的转换。

5.函数模板的显示指定

对于有些模板函数,不能给出所有的模板实参,导致编译器无法推断出函数模板实参情况,如下:

template<class T1,class T2, class T3>
T1 sum(T2 t1, T3 t2)
{return t1 + t2;
}

这种情况我们应该显示指定模板的实参情况,模板的实参的显示指定通过在函数名之后参数列表之前添加尖括号的方式进行指定,如下操作:

auto ret = sum<int,int,double>(10, 10.0);//显示的将T1指定为int,T2指定为int,T3指定为double。

事实上,以上调用只需要指定T1即可。T2,T3可以采用隐式的方式进行指定。

auto ret = sum<int>(10, 10.0);//显示的将T1指定为int,T2隐式指定为int,T3隐式指定为double。

但是如果这样设计则只能显示的指定三个参数。

template<class T1,class T2, class T3>
T3 sum(T1 t1, T2 t2);auto ret = sum<int>(10, 10.0);//错误,不能隐世指定
auto ret = sum<int,int,double>(10, 10.0);//正确,隐式指定所有的参数类型。

C++学习笔记-------模板(template)相关推荐

  1. 设计模式学习笔记——模板(Template)模式

    设计模式学习笔记--模板(Template)模式 @(设计模式)[设计模式, 模板模式, template, 模板方法] 设计模式学习笔记模板Template模式 基本介绍 模板案例 类图 实现代码 ...

  2. C++学习笔记:模板

    C++学习笔记:模板 1.函数模板 2.类模板 2.1类模板注意事项 2.2类模板中函数的创建时机 2.3类模板对象作函数参数时 2.4类模板与继承 2.5类模板分文件编写 2.6类模板友元 2.6. ...

  3. 图论01.最短路专题_学习笔记+模板

    图论01.最短路专题_学习笔记+模板 一.定义与性质 ● 需要的前导知识点 路径 最短路 有向图中的最短路.无向图中的最短路 单源最短路.每对结点之间的最短路 ● 最短路的性质 对于边权为正的图,任意 ...

  4. C++模板学习笔记——模板实参

    对于函数模板,编译器通过隐式推断模板实参.其中,从函数实参来确定模板实参的过程被称为模板实参推断.在模板实参推断过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定 ...

  5. image是否有disabled属性_Vue学习笔记 模板语法、计算属性

    点击上方"蓝字"关注我们吧! vue学习笔记 官网:https://cn.vuejs.org/v2/guide/ 1.vue体验 demo示例: image.png 示例代码: & ...

  6. C++学习笔记—模板与STL

    C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 例如生活中的模板 一寸照片模板 PPT ...

  7. [C++]学习笔记——模板

    针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用. 1.模板 1.1模板的概念 模板就是建立通用的模具,大大提高复用性 日常生活例子帮助理解:一寸照片模板.PPT模板 1.2函数模板语 ...

  8. C++ STL学习笔记 : 1. template 模板函数

    本篇文章是学习C++ STL库的第一篇笔记,主要记录了使用template关键字创建模板函数的方法. 下面用一个非常简单的例子解释模板函数的用法 : #include <iostream> ...

  9. 设计模式学习笔记(八)—Template Method模式

    factory模式(包括简单工厂和抽象工厂),Strategy模式,Template method模式是学习Spring框架必不可少的. <设计模式>一书对Template Method模 ...

最新文章

  1. synchronized锁的基本用法
  2. python求两个列表的并集.交集.差集方法
  3. 员外带你读论文:SeqGAN论文分享
  4. 工业局的云计算机,广州市海珠区科技工业商务和信息化局方奕涛局长带队二次调研云算...
  5. 《力学》课时三常见力和牛顿三定律
  6. SAP License:雾里看花系列——SAP应用应该更关注业务过程
  7. 阅读下面程序,请回答如下问题:
  8. java上课签到如何写_java签到程序怎么设置?学生考勤程序怎么写?
  9. 如何在linux运行exe文件,在Deepin系统下直接运行exe文件的方法
  10. 在线HTTP POST/GET接口测试工具
  11. Xmapp安装配置和连接MySQL
  12. 计算机的运算符号,运算符号包括哪些
  13. heka 输出到mysql_Heka配置的详细介绍
  14. 有些东西,你学不来的
  15. _, predicted = torch.max(outputs, 1),_,的作用
  16. 05无人机动态模型(姿态表示与控制理论)2020-08-15
  17. SSRPanel 后端配置对接教程
  18. 英文人名及含意(转)
  19. 侍魂胧月传说显示服务器满了,侍魂胧月传说满级之后做什么 满级每日必做任务详解[多图]...
  20. PCB电路板3D模型3D渲染思路

热门文章

  1. Style的所有属性
  2. [CentOS] 三、安装 i3
  3. Android热缓解策略
  4. 【JokerのZYNQ7020】PS_LWIP_POLL。
  5. Nodejs开发技巧集锦(4):使用multiparty获取上传的表单文件
  6. 小程序带参数二维码快速生成
  7. 黑马十次方项目day08-11 消息总线组件SpringCloudBus
  8. 将DVD / Blu-ray / UHD动画复制到空白光盘的方法
  9. 大学英语拓展课程系列计算机英语课后答案,《科技英语》课后习题答案完整版.doc...
  10. 使用element-ui的checkbox插件报错vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'length' of un