C++编程思想:模板
文章目录
- 模板的特性1:需要遵守约定
- 模板类型的模板参数
- 函数成员模板和类成员模板
- 模板特化以及模板重载
- 模板中的符号解析
模板的特性1:需要遵守约定
模板将类型以一个标识符替代,想要使用模板就需要遵守模板对这个标识符的要求,比如对标识符有什么成员变量以及成员函数。
#include <iostream>
#include <vector>
using namespace::std;//*****************这是一个模板类的实现,展示模板的特性之一:约定性*******************************
template<class T> class X
{public:typename T::id i; //约定类型T中有id这个类型,并且创建一个id类型的变量,typename是关键字,用typename 告诉编译器T::id是一个类型标识符
public:void f() {i.g(); //约定i中有g()这个函数}
};class Y
{public:class id{public:void g() {cout << "this is the Y::id object function g()" << endl;}};
};/*
int main() {X<Y> xy;xy.f();
}
*/
模板类型的模板参数
//********************************这是一个模板类型的模板参数案例****************************
template <class T, template <class> class Seq> //T是一个类型,Seq是一个模板类型,这个模板类型有一个参数(无需写出参数名)
class Container
{public:Seq<T> seq; //Seq模板类型中的类型参数是T
public:void printSeq() {cout << "the size of seq : " << seq.size() << endl;}void push_back(T t){seq.push_back(t);}
};
template<class T> class Vec
{public:vector<T> vec;
public:void push_back(T t){vec.push_back(t);}size_t size() {return vec.size();}
};/*
int main()
{Container<int, Vec> cv;cv.push_back(1);cv.push_back(2);cv.printSeq();}
*/
函数成员模板和类成员模板
//***********************成员函数中的模板:分为函数成员模板和类成员模板*********************************
template <class T> class com
{public:T t;com(const T& tt) :t(tt){std::cout << "t : " << t << endl;}template <class U> com(const com<U>& u) : t(u.t) //成员函数模板{std::cout << "u : " << t << endl;}
};template <class T> class outer
{public:template<class R> class iner //成员函数类{public://template<class T> template<class R>void f(){std::cout << "out " << typeid(T).name() << endl;std::cout << "inner " << typeid(R).name() << endl;std::cout << "this " << typeid(*this).name() << endl;}};
};/*
int main() {com<float> a(1);com<double> b(a);outer<float>::iner<int> ou;ou.f();outer<float>::iner<int> oc(ou); //这里会调用拷贝构造函数
}*/
模板特化以及模板重载
在实例化模板时,优先考虑特化程度高的模板,比如有指针修饰符修饰的模板或者直接特化的模板,若特化程度高的模板可以匹配就使用特化程度高的模板,当然匹配度是更重要的指标。
//*****************模板特化以及模板重载************************************
#include<stack>
template <class StackType>
void emptyTheStack(StackType& stk)
{cout << "this is stackType" << endl;
}template <class StackType>
void emptyTheStack(stack<StackType*> & stk) //经过指针特化的模板,当实例化为参数为指针时优先调用此模板
{cout << "this is stack<StackType*>" << endl;
}template<>
void emptyTheStack(float& stk) //直接float 类型,显示特化
{cout << "this is float& stk" << endl;
}void emptyTheStack(int stk) //重载模板函数
{cout << "this is int stk" << endl;
}int main()
{double a = 1;emptyTheStack(a); //调用第一个模板float b = 1;emptyTheStack(b);//调用第三个模板stack<float*> c;emptyTheStack(c); //调用第二个模板int d = 1;emptyTheStack(d);//调用最后一个重载函数
}
模板中的符号解析
如果符号定义涉及到未确定类型,在编译的第一阶段只会在已经定义的符号表中查找该符号,不会到不确定类型中查找该符号。
//********************************关联不确定类型标识符的编译*************************
#include<algorithm>
#include<typeinfo>
using std::cout;
using std::endl;void g() { cout << "global g()" << endl; } //全局定义template <class T> class YY
{public :void g(){cout << "Y<" << typeid(T).name() << ">::g()" << endl;}void h(){cout << "Y<" << typeid(T).name() << ">::h()" << endl;}typedef int E; //局部定义
};typedef double E; //全局定义//一个全局定义的模板函数
template<class T> void swap(T& t1, T& t2)
{cout << "global swap" << endl;T temp = t1;t1 = t2;t2 = temp;
}template<class T> class XX :public YY<T>
{public:E f() //E的返回类型是double{g(); //这个会编译成全局函数,而不是YY中的函数定义体,因为YY中的函数定义体是关联未定类型的,不会优先编译this->h();//这是YY中的T t1 = T(0);T t2 = T(1);cout << "t1: " << t1 << endl;cout << "t2: " << t2 << endl;swap(t1, t2);std::swap(t1, t2);cout << "E type: " << typeid(E).name() << endl;return E(t2);}
};
int main()
{XX<int> x;cout << x.f() << endl;
}
C++编程思想:模板相关推荐
- 几种常用编程语言的编程思想和方法 转
搞软件的人,编程语言的掌握是基本功,如果单单是学习语法,最慢的一周之内也应该可以搞定(个人认为 语法层面c++是最复杂的).不幸的是,软件的本质是逻辑,解决方案的设计是要借助某种解决问题或编程的思想的 ...
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- C++编程思想重点笔记(下)
上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串, ...
- Val编程-val系列编程思想
利用Val语言可以编写出各种各样的应用程序.正如windows phone面临的窘境一样,受众太小,市场不大.应用程序不多,所以也谈不上成熟.国内的应用程序基本上就是简单的小程序,谈不上什么编程思想. ...
- CoreJava学习第五课 --- 进入第二阶段:面向对象编程思想
面向对象编程思想 1.面向过程 从计算机执行角度出发 ,代码执行过程核心为从程序的运行过程出发,构建编程思路,例: 哥德巴赫猜想 // 面向过程1 用户输入一个数n2 验证数字的正确性2.1 正确 ...
- python递归 及 面向对象初识及编程思想
递归 及 面向对象初识及编程思想 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...
- python中的递归思想_〖Python〗-- 递归、面向对象初识及编程思想
[递归.面向对象初识及编程思想] 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...
- 面向对象编程思想 以及类与对象
一.面向对象编程思想 众所周知,我们常见的编程思想有面向过程和面向对象两种,像我们最基础的c语言,就是一种以过程为中心的编程思想,不关注具体的事件和对象而是针对于解决问题的思路和目标,这种编程思想由于 ...
- 71.JAVA编程思想——JAVA与CGI
71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST ...
- Java编程思想日志
Thinking In Java的作者是大牛!做事要站在巨人的肩膀上有助于提高效率和开阔眼界!建议学习java的小伙伴儿有时间可以抽空了解一下,以下内容为读书笔记,比较杂乱,仅供参考,推荐阅读原著: ...
最新文章
- 2017年高级二级计算机考试试题,2017年计算机二级高级Office考试试题操作题
- MATLAB 多项式
- 瑞士银行开户条件有哪些,瑞士银行开户的流程及注意事项是什么?
- (转)使用DataGridView控件常见问题解答
- 华为电视鸿蒙系统好用吗,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可
!【手机吧】_百度贴吧...
- Leetcode--695. 岛屿的最大面积
- 开源 java CMS - FreeCMS2.5 标签 infoPage
- (11)Xilinx BRAM或者ROM初始化文件.COE制作(FPGA不积跬步101)
- java 定义方法_java如何定义方法
- ElasticSearch出现Cluster state has not been recovered yet, cannot write to the [null] index的解决办法
- 数学建模(一)层次分析法
- CodeProject是个好地方
- oracle中isnumber函数,Oracle 函数isnumber问题
- 验证集与测试集的区别
- (转载)SoftIce的安装、配置以及一些基本操作
- 机器学习中的数学——Momentum(Gradient Descent with Momentum, GDM)
- tools: rm -vf !(*.sh) 删除 除了
- Win系统速览桌面功能失效 - 解决方案
- 记录---Rosalind之problemsSolutions__0002
- 怎样进行大数据的入门级学习?
热门文章
- Killzone's AI: dynamic procedural combat tactics
- SQL2005 数据库数据同步
- 假如生活欺骗了你!——Leo网上答疑(14)
- 电源pd功能的充电器_PD快充充电器电源芯片和普通充电器电源芯片有什么区别?...
- mpvue 踩坑之src数据绑定出错
- java double溢出_java – 可以加倍或BigDecimal溢出?
- vue 按钮多次点击重复提交数据
- ANN:DNN结构演进History—LSTM网络
- SSM-SpringMVC-07:SpringMVC中处理器映射器
- Vue.js分页组件实现:diVuePagination