文章目录

  • 模板的特性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++编程思想:模板相关推荐

  1. 几种常用编程语言的编程思想和方法 转

    搞软件的人,编程语言的掌握是基本功,如果单单是学习语法,最慢的一周之内也应该可以搞定(个人认为 语法层面c++是最复杂的).不幸的是,软件的本质是逻辑,解决方案的设计是要借助某种解决问题或编程的思想的 ...

  2. Java中的泛型 --- Java 编程思想

    前言 ​ 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...

  3. C++编程思想重点笔记(下)

    上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串, ...

  4. Val编程-val系列编程思想

    利用Val语言可以编写出各种各样的应用程序.正如windows phone面临的窘境一样,受众太小,市场不大.应用程序不多,所以也谈不上成熟.国内的应用程序基本上就是简单的小程序,谈不上什么编程思想. ...

  5. CoreJava学习第五课 --- 进入第二阶段:面向对象编程思想

    面向对象编程思想 1.面向过程 ​ 从计算机执行角度出发 ,代码执行过程核心为从程序的运行过程出发,构建编程思路,例: 哥德巴赫猜想 // 面向过程1 用户输入一个数n2 验证数字的正确性2.1 正确 ...

  6. python递归 及 面向对象初识及编程思想

    递归 及 面向对象初识及编程思想 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...

  7. python中的递归思想_〖Python〗-- 递归、面向对象初识及编程思想

    [递归.面向对象初识及编程思想] 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...

  8. 面向对象编程思想 以及类与对象

    一.面向对象编程思想 众所周知,我们常见的编程思想有面向过程和面向对象两种,像我们最基础的c语言,就是一种以过程为中心的编程思想,不关注具体的事件和对象而是针对于解决问题的思路和目标,这种编程思想由于 ...

  9. 71.JAVA编程思想——JAVA与CGI

    71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST ...

  10. Java编程思想日志

    Thinking In Java的作者是大牛!做事要站在巨人的肩膀上有助于提高效率和开阔眼界!建议学习java的小伙伴儿有时间可以抽空了解一下,以下内容为读书笔记,比较杂乱,仅供参考,推荐阅读原著: ...

最新文章

  1. 2017年高级二级计算机考试试题,2017年计算机二级高级Office考试试题操作题
  2. MATLAB 多项式
  3. 瑞士银行开户条件有哪些,瑞士银行开户的流程及注意事项是什么?
  4. (转)使用DataGridView控件常见问题解答
  5. 华为电视鸿蒙系统好用吗,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可 !【手机吧】_百度贴吧...
  6. Leetcode--695. 岛屿的最大面积
  7. 开源 java CMS - FreeCMS2.5 标签 infoPage
  8. (11)Xilinx BRAM或者ROM初始化文件.COE制作(FPGA不积跬步101)
  9. java 定义方法_java如何定义方法
  10. ElasticSearch出现Cluster state has not been recovered yet, cannot write to the [null] index的解决办法
  11. 数学建模(一)层次分析法
  12. CodeProject是个好地方
  13. oracle中isnumber函数,Oracle 函数isnumber问题
  14. 验证集与测试集的区别
  15. (转载)SoftIce的安装、配置以及一些基本操作
  16. 机器学习中的数学——Momentum(Gradient Descent with Momentum, GDM)
  17. tools: rm -vf !(*.sh) 删除 除了
  18. Win系统速览桌面功能失效 - 解决方案
  19. 记录---Rosalind之problemsSolutions__0002
  20. 怎样进行大数据的入门级学习?

热门文章

  1. Killzone's AI: dynamic procedural combat tactics
  2. SQL2005 数据库数据同步
  3. 假如生活欺骗了你!——Leo网上答疑(14)
  4. 电源pd功能的充电器_PD快充充电器电源芯片和普通充电器电源芯片有什么区别?...
  5. mpvue 踩坑之src数据绑定出错
  6. java double溢出_java – 可以加倍或BigDecimal溢出?
  7. vue 按钮多次点击重复提交数据
  8. ANN:DNN结构演进History—LSTM网络
  9. SSM-SpringMVC-07:SpringMVC中处理器映射器
  10. Vue.js分页组件实现:diVuePagination