两种模板(C++03) -> 四种模板(C++14)

传统C++只有两种模板,分别是类模板和函数模板。而最新的C++标准中总共有四种模板,这是因为C++11引入了别名模板,而C++14则引入了变量模板。

template<class T>  和  template<typename T> 都可以用来定义函数模板类模板,在使用上,他们俩没有本质的区别。

具体为;class用于定义类,在模板引入c++后,最初定义模板的方法为:template,这里class关键字表明T是一个类型。后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字。它的作用同class一样表明后面的符号为一个类型。这样在定义模板的时候就能够使用以下的方式了: template.在模板定义语法中关键字class与typename的作用全然一样。

函数模板针对仅参数类型不同的函数;类模板针对仅数据成员和成员函数类型不同的类。

函数模板:

声明及定义形式为:

template <class 形参名,class 形参名,......> 返回类型 函数名(参数列表)
{函数体
}

在头文件

template < class T>
bool compare(T t1, T t2)
{if (t1 > t2){return true;}else{return false;}
}

调用的地方: compare<int>(1,2);

延伸到默认模板参数

函数模板的默认模板参数没有此约束。但如果是默认参数值还是要由右到左

template <class T1 = float, int i = 0, class T2 = string>
void funt1(T1 t1, T2 t2 = "bbbb" ) {cout << t1 << i<< t2 << endl;
}funt1("a");

template是定义模板函数的关键字;template后面的尖括号不能省略;typename(或class)是声明数据类型參数标识符的关键字。用以说明它后面的标识符是数据类型标识符。这样,在以后定义的这个函数中,凡希望依据实參数据类型来确定数据类型的变量,都能够用数据类型參数标识符来说明,从而使这个变量能够适应不同的数据类型。

如:template <class T> void swap(T& a,T& b){}

使用函数模板有2种方式

1.自动类型推到调用swap(a,b);

2.显性类型推到调用swap<int>(a,b);

实际应用

int  a =1;

int b= 2;

swap<int>(a,b);

类模板:

其格式为:

template<class  形参名,class 形参名,…>   class 类名
{ ...
};

foo 为类名,在类定义体中,如採用通用数据类型的成员,函数參数的前面需加上T。当中通用类型T能够作为普通成员变量的类型,还能够作为const和static成员变量以及成员函数的參数和返回类型之用。

如:

template <class T>class A {public: T a;T b;   T hy(T c, T &d);};

在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。

用类模板定义对象的写法如下:

类模板名<真实类型参数表> 对象名(构造函数实际参数表);

如果类模板有无参构造函数,那么也可以使用如下写法:

类模板名 <真实类型参数表> 对象名;

template<class T1,class T2>
class A
{
public:T1 g(T1 a, T2 b);A();
};template<class T1, class T2>
A<T1, T2>::A()
{}template<class T1, class T2>
T1 A<T1, T2>::g(T1 a, T2 b)
{return a + b;
}int main()
{A<float, int> ta;ta.g(1.1, 2);return 0;
}

进一步研究:类模板与继承

1.当子类不是类模板,而继承的父类是一个类模板时,子类在声明的时候要指定出父类中的类型;

//类模板与继承
template<typename T>
class Basic {
public:T age;
};

子类不是类模板时,可以直接调用基类类模板的函数,因为基类的模板类型已经指定了

//此处需要指定父类中的模板数据类型
class t1 :public Basic<string> {};
void func1() {t1 ttt;ttt.age = "abc";cout << ttt.age << endl;
}

2.子类是类模板,继承的父类也是一个类模板时。

template <class T>
class tem {
public:T  aa;int bb;void func(T t);void funct() {int dd = 1;}
};template <class T1,class T2>
class tem3 :public tem<T1>
{
public:using tem<T1>::funct;int cc;T2  dd;void functem3() {funct();}};
 tem3<int, int> tt3;tt3.functem3();

3. 类模板的默认模板参数需要从右到左依次;

template <class T1 = int, int i = 0, class T2 = string>
class ctem
{
public:T1 t1;void fun1(T2 t2);
};template <class T1 /*= int*/, int i /*= 0*/, class T2 /*= string*/>
void ctem<T1, i, T2>::fun1(T2 t2)
{}
ctem<> tem;
tem.fun1("q");

4.当子类类模板调用基类模板的函数时:直接调用会报错,见下图

解决办法可以有3种办法:
1.在调用动作之前加上“this->”
2.使用using声明式(using tem<T1>::funct;)
3.明白指出被调用的函数位于base class内(baseclass::func())最好不用这办法,因为实现不了虚函数的多态。

别名模板(alias template)
别名模板:带模板参数的类型别名
类型别名(type alias)是C++11新引入的语法形式:
using newtype = oldtype;
在语法功能上,它相当于传统C/C++语言中的typedef语句:
typedef oldtype newtype;
可以看出,类型别名中原有类型和别名的定义顺序与typedef语句正好相反。除此之外,类型别名与typedef语句还有一点不同,类型别名可以加上模板参数形成别名模板:
template<typename ...> using newtype = oldtype<...>;
注:C++11引入类型别名意图取代typedef语句的原因在于:无法直接在typedef语句的基础上直接构建别名模板。这是因为typedef语句自身存在某些局限性,直接给typedef加上模板参数会带来语法解析上的问题。

template<typename T, typename U>
struct A;
 
template<typename T>
struct B
{
    typedef A<T, int> type;
};
 
template<typename T> using C = A<T, int>;
 
template<typename T> using D = typename B<T>::type;

代码说明:
假设我们有一个带两个模板参数T和U的类模板A。现在我们需要声明一个只带一个模板参数T的类模板,使其等价于模板参数U为int类型的A模板。也就是说,我们需要一个模板参数T任意,模板参数U为int类型的A模板的别名,或者说A<T, int>的别名。
在C++11之前,答案为类模板B。要定义类型别名,必然要使用typedef。但由于typedef不能带模板参数,所以typedef必须被嵌入到一个带模板参数的类模板里面。在模板参数为T的类模板B里面,类型type被定义成A<T, int>的别名。也就是说typename B<T>::type被定义成了A<T, int>的别名。
在C++11之后,答案为别名模板C。类型别名直接就可以带模板参数。C<T>直接被定义成了A<T, int>的别名。
如果出于某种原因,在定义别名的时候无法使用类模板A而只能使用类模板B,别名模板也能发挥作用。这里D<T>直接被定义成了typename B<T>::type的别名。由于后者是A<T, int>的别名,所以D<T>其实也是A<T, int>的别名。
这段代码展示了别名模板的主要用途:1.为部分模板参数固定的类模板提供别名。2.为类模板中嵌入的类型定义提供别名。

变量模板(variable template)
变量模板:变量的家族
变量模板是C++14新引入的模板形式,在语法功能上它相当于一个没有参数但是有返回值的函数模板,相对于后者,变量模板在语法上更清晰,更能反映编程者的意图。
template<typename ...> type variable;

#include <iostream>
#include <iomanip>
using namespace std;
// 函数模板
template<class T>
constexpr T pi_fn()
{
    return T(3.1415926535897932385);
}
// 变量模板
template<class T>
constexpr T pi = T(3.1415926535897932385);
 
int main()
{
   cout << pi_fn<int>() << pi<int> << '\n'; // 33
   cout << setprecision(10) << pi<float> << '\n'; // 3.141592741
   cout << setprecision(10) << pi<double> << '\n'; // 3.141592654
}

C++中 模板Template的使用相关推荐

  1. Vue中 模板template的四种写法

    <div id="app"><h1>我是直接写在构造器里的模板1</h1> </div><template id=" ...

  2. C++中模板template typename T

    template <typename Dtype>. 网上解释的非常多,觉得比较啰嗦,其实就是一个类型模板. 比如我们要计算两个数的加法,针对不同类型可能需要设计不同类型的函数,那么tem ...

  3. C++中的模板template

    1.Cpp中的模板template 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码.模板是创建泛型类或函数的蓝图或公式.库容器,比如迭代器和算法都是泛型编程的例子,它们都使用了 ...

  4. 【小白学习C++ 教程】十五、C++ 中的template模板和泛型

    @Author:Runsen template模板在 C++ 中一个简单但非常强大的工具.简单的想法是将数据类型作为参数传递,这样我们就不需要为不同的数据类型编写相同的代码. C++ 添加了两个新关键 ...

  5. ie模版字符串_字符串模板、模板字符串、Vue中使用template等等。

    1:模板字符遇新是直朋能到串 传统的一如分算需上来处一定迹面数一跳这件我子作JS语言,输出模板新直能分支调二浏页器朋代说,事刚需求是这样写的: $('#result').append( 'There ...

  6. 如何增加MOSS 2007中list template和site template的最大值

    在不同的站点和列表间传递相同设置的时候, 把已有的站点和列表存为模板是非常方便的一种方式. 然而, 默认情况下, 站点和列表模板的大小是有上限的, 为10MB. 如果你试图存一个超过10MB的站点为模 ...

  7. 多个so中模板单例的多次实例化

    在Android打包项目时,发现登录功能不能使用了,logcat中也没发现什么问题,最后一行一行log定位到了问题.原来是一个so文件中的构造函数被初始化二次! 这个单例是通过继承模板来实现的(暂时不 ...

  8. 关于 underscore 中模板引擎的应用示例

    //关于 underscore 中模板引擎的应用示例 <!doctype html> <html> <head> <meta charset="ut ...

  9. vue 模板 html 表达式,Vue 模板template、指令directive、修饰符

    模板 template template的三种写法 写法一:Vue完整版,写在HTML里 //html {{n}} +1 //vue new Vue({ el: '#xxx', data(){ ret ...

  10. C++:18---函数模板(template)

    一.模板的定义 template<typename T> 以关键字template开头,后面跟一个模板参数列表,列表里面用逗号将多个模板参数隔开定义的注意事项 模板的编译 当编译器遇到一个 ...

最新文章

  1. 京东程序员回应“被猝死”:我还活着,还在写代码
  2. 天猫精灵怎么和台式计算机链接,天猫精灵怎么连接电脑
  3. VC中TXT文件的存取
  4. python3安装cocos2d_(3)在Windows7上搭建Cocos2d-x
  5. Python模块制作
  6. php 开启 pathinfo,nginx下PHP开启pathinfo模式
  7. UI Prototype Design IDE( 界面原型设计工具 )
  8. 【简便解法】1079 延迟的回文数 (20分)_31行代码AC
  9. 面向智能电网的电力大数据存储与分析应用
  10. 数据结构---array
  11. JS 设计模式 一(接口)
  12. mysql5.7 之 sql_mode=only_full_group_by问题
  13. Shell脚本编程之(二)简单的Shell脚本练习
  14. Linux 数据校验md5sum
  15. java 俄罗斯方块原理,俄罗斯方块设计原理
  16. MoveIt! 学习笔记13 - KDL/IKFAST/TRAC-IK运动学求解器区别
  17. 1010001b 1101110b怎么用计算机,计算机组成原理计算题
  18. 六十六条经典禅语名句
  19. 服务器 最新 配置,常见的服务器配置参数介绍
  20. 如何在多可系统里设置腾讯通RTX参数

热门文章

  1. c/c++再学习:C与Python相互调用
  2. EJB2的3本好书第3本 EJB Cookbook
  3. MRD市场需求文档结构
  4. Screen - BOM对象
  5. 面向对象技术之系统分析:类图
  6. 步步为营:因为数据库正在使用,所以无法获得对数据库的独占访问权
  7. Gcc编译选项 -E
  8. Bing Maps进阶系列二:使用GeocodeService进行地理位置检索
  9. 微信小程序的模块化开发,提高效率第一篇
  10. 资源管理器和计算机的功能基本相同吗,“资源管理器”和“计算机”的功能基本相同...