C++深入了解模板的使用

目录
  • 一.泛型编程
  • 二.函数模板
    • 1.函数模板概念
    • 2.函数模板格式
    • 3.函数模板的原理
  • 三.类模板

一.泛型编程

泛型编程:不再是针对某种类型,能适应广泛的类型,跟具体的类型无关的代码

如何实现一个通用的交换函数呢?

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}

使用函数重载虽然可以实现,但是有一下几个不好的地方: 1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增 加对应的函数 2. 代码的可维护性比较低,一个出错可能所有的重载均出错

因此我们需要告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码

二.函数模板

模板分为:函数模板,类模板

1.函数模板概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生 函数的特定类型版本。

2.函数模板格式

template<typename T>

返回值类型 函数名(参数列表){}

说明:

1.template<class T> 和 template<typename T>在此暂时认为一样,template<struct T>是 错误的 ,没有这种写法

2.T是type的缩写,T不一定写T,可以写任意字母,比如X,t ……但是习惯写为T

举例:

template<typename T>    //或template<class T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
int main()
{
	int a = 0, b = 1;
	double c = 2.2, d = 3.3;
	swap(a, b);
	swap(c, d);
	return 0;
}

swap(a, b);swap(c, d); 调用的是同一个函数吗?

答:不是同一个。底层汇编可以看出不是同一个,如果调试时发现走的是同一个函数,其实是编译器的优化导致。

实际上以后swap函数都不用自己写了,库中有模板,直接用就行

3.函数模板的原理

在编译器编译阶段 ,对于模板函数的使用, 编译器需要根据传入的实参类型来推演生成对应类型 的函数 以供调用。比如: 当用 double 类型使用函数模板时,编译器通过对实参类型的推演,将 T 确定为 double 类型,然后产生一份专门处理 double 类型的代码 ,对于字符类型也是如此。 模板的实例化:

三.类模板

类模板的定义格式

template < class T1 , class T2 , ..., class Tn >

class 类模板名

{

// 类内成员定义

};

举例:调用 Stack<int> st1; 时,用int替换模板中的T。调用 Stack<double> st1; 时,用double替换模板中的T

// 类模板
template<class T>
class Stack
{
public:
	Stack(int capacity = 0)
	{
		_a = new T[capacity];
		_capacity = capacity;
		_top = 0;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[] _a;
		_capacity = 0;
		_top = 0;
	}
	void Push(const T& x)
	{}
private:
	T* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack<int> st1; // int
	st1.Push(1);
	Stack<double> st2; // double
	st2.Push(2.2);
	return 0;
}

到此这篇关于C++深入了解模板的使用的文章就介绍到这了,更多相关C++模板内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++分离讲解模板的概念与使用

    目录 泛类编程 函数模板 函数模板的概念 函数模板的使用 函数模板的实例化 函数模板的匹配原则 类模板 类模板的定义格式 类模板的实例化 泛类编程 学习模板,首先我们需要了解一下什么是泛类编程 #include<iostream> using namespace std; int add(int a, int b) { return a + b; } double add(double a, double b) //这两个add构成了函数重载 { return a + b; } int mai

  • C++模板全方位深入解读

    目录 1.泛型编程 2.函数模板 概念 函数模板的格式 函数模板的原理 函数模板的实例化 隐式实例化 显式实例化 模板参数的匹配原则 3.类模板 (1) 类模板的定义格式 (2) 类模板的实例化 4.非类型模板参数 5.模板特化 (1)函数模板的特化 (2)类模板的特化 全特化 偏特化 6.模板的分离编译 问题分析 1.泛型编程 如何实现一个通用的交换函数? 这点函数重载可以做到,比如一下Swap函数的重载,分别重载了俩种不同参数类型的Swap void Swap(int& x, int&

  • C++超详细讲解模板的使用

    目录 一.函数模板 1.1函数模板概念 1.2 函数模板格式 1.3 函数模板的原理 1.4 函数模板的实例化 二.类模板 2.1 类模板的定义格式 2.2类模板的实例化 总结 一.函数模板 1.1函数模板概念 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本. 1.2 函数模板格式 template<typename T1, typename T2,…,typename Tn> 返回值类型 函数名(参数列表){} template<

  • 如何C++使用模板特化功能

    目录 前言: 1.函数模板的特化 2.类模板的特化 前言: 通过定义模板,使得函数或者类不依赖于特定的类型,这样大幅提升了代码的复用性. 然而,不管是类模板还是函数模板,对所有的类型都是采用相同的处理方式(同一份代码).为此,C++提出了“模板特化的概念”,对特定类型提供模板的改造. 比如,对于函数模板来说,可以通过特化指定特定的类型,针对此特定类型对函数体内容进行重写,使得函数对特定类型实现特定功能. 注意: 按照语法,对函数模板和类模板进行特化后,就变为普通函数和普通的类,而不再是模板. 1

  • C++模板Template详解及其作用介绍

    目录 1. 模板 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 2.6声明定义分离 3. 类模板 3.1 类模板格式 3.2 类模板的实例化 3.3 类模板中函数放在类外进行定义时 4. 模板分离编译 4.1 什么是分离编译 4.2 模板的分离编译 5. 缺省值与返回值 6. 总结 1. 模板 首先模板分为函数模板和类模板 想到模板,就会联想到泛型编程 泛型编程:编写与类型无关的通用代码,是代码复用的一种手

  • C++ 深入浅出探索模板

    目录 非类型模板参数 模板特化 函数模板特化 类模板特化 全特化 偏特化 模板分离编译 模板的分离编译 解决方法 总结 非类型模板参数 模板参数分类类型形参与非类型形参. 类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称. 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用. 注意: 浮点数,类对象以及字符串是不允许作为非类型模板的. 非类型的模板参数必须在编译期就能确认结果. 模板特化 有时候,编译默认函数模板

  • C++将模板实现放入头文件原理解析

    目录 写在前面 例子 原因 分析 解决方案 方案一 方案二 参考 写在后面 写在前面 本文通过实例分析与讲解,解释了为什么C++一般将模板实现放在头文件中.这主要与C/C++的编译机制以及C++模板的实现原理相关,详情见正文.同时,本文给出了不将模板实现放在头文件中的解决方案. 例子 现有如下3个文件: // add.h template <typename T> T Add(const T &a, const T &b); // add.cpp #include "

  • C++11中模板隐式实例化与显式实例化的定义详解分析

    目录 1. 隐式实例化 2. 显式实例化声明与定义 3. 显式实例化的用途 1. 隐式实例化 在代码中实际使用模板类构造对象或者调用模板函数时,编译器会根据调用者传给模板的实参进行模板类型推导然后对模板进行实例化,此过程中的实例化即是隐式实例化. template<typename T> T add(T t1, T2) { return t1 + t2; } template<typename T> class Dylan { public: T m_data; }; int ma

  • C++可变参数模板的展开方式

    文章目录 前言可变参数模板的定义参数包的展开递归函数方式展开逗号表达式展开enable_if方式展开折叠表达式展开(c++17) 总结 前言 可变参数模板(variadic templates)是C++11新增的强大的特性之一,它对模板参数进行了高度泛化,能表示0到任意个数.任意类型的参数.相比C++98/03这些类模版和函数模版中只能含固定数量模版参数的“老古董”,可变模版参数无疑是一个巨大的进步. 如果是刚接触可变参数模板可能会觉得比较抽象,使用起来会不太顺手,使用可变参数模板时通常离不开模

  • thinkPHP5框架渲染模板的3种方式简述

    本文实例讲述了thinkPHP5框架渲染模板的3种方式.分享给大家供大家参考,具体如下: 默认情况下,控制器的输出全部采用return的方式,无需进行任何的手动输出,系统会自动完成渲染内容的输出. 在控制器里渲染模板 namespace app\index\controller; use think\view; class Index{ public function index(){ $view = new view(); return $view->fetch('index'); } } 直

  • Sublime Text新建.vue模板并高亮(图文教程)

    本文介绍了 Sublime Text新建.vue模板并高亮(图文教程),分享给大家,也给自己留个笔记. 准备工作 下载安装新建文件模板插件 SublimeTmpl 下载安装vue语法高亮插件 Vue Syntax Highlight Sublime Text安装插件的方法有两种: 1.使用Sublime Text自带的安装库 Package Control 去安装 点击菜单栏的 Preferences -> Package Control 或使用快捷键 CTRL+SHIFT+P 打开终端窗口,输

  • laytpl 精致巧妙的JavaScript模板引擎

    laytpl是一款颠覆性的JavaScript模板引擎,它用巧妙的实现方式,将自身的体积变得小巧玲珑,不仅性能接近极致,并且还具备传统前端引擎的几乎所有功能.所有的变身魔法都由不到1KB的代码创造,这仿佛是一场革命,又或者不是,但毋庸置疑的是,laytpl的确在用最轻量的方式呈现给世人.如果你从未接触这方面的应用,没关系,下面的讲述将会让你迫不及待地选择laytpl,从此更好地把握页面的数据渲染,走上人生巅峰! laytpl优势 •性能卓绝,执行速度比号称性能王的artTemplate.doT还

  • AngularJS入门教程之静态模板详解

    为了说明angularJS如何增强了标准HTML,我们先将创建一个静态HTML页面模板,然后把这个静态HTML页面模板转换成能动态显示的AngularJS模板. 在本步骤中,我们往HTML页面中添加两个手机的基本信息,用以下命令将工作目录重置到步骤1. git checkout -f step-1 请编辑app/index.html文件,将下面的代码添加到index.html文件中,然后运行该应用查看效果. app/index.html <ul> <li> <span>

  • 详解在 Angular 项目中添加 clean-blog 模板

    在 Angular 项目中添加 clean-blog 模板 clean-blog 博客模板下载 clean-blog 或者在下面链接下载 startbootstrap-clean-blog-4-dev.zip 解压并拷贝 解压下载的文件,将所有文件拷贝到 assets/clean-blog 目录下 拷贝代码 将 clean-blog 的 index.html 内容拷贝到 app.component.html <!--The whole content below can be removed w

  • 模板视图和AngularJS之间冲突的解决方法

    本文实例讲述了模板视图和AngularJS之间冲突的解决方法.分享给大家供大家参考,具体如下: 问题: 在php的mvc视图中,我们需要在加载的过程中 传递一些数据给模板: 如: 这里是某个 controller $data['users'] = {something from databases}; $this->load->view('home/index',$data); 这里是对应的视图 <div ng-controller="loadData"> &l

  • AngularJS 路由和模板实例及路由地址简化方法(必看)

    最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽,其中爽就爽在它的开发模式,使得代码更加的清晰.更加具有可读性.更简洁.更具有维护性.但是在使用AngularJS开发的过程中也有让我头疼的地方,那就是目前前端框架更多的还是以Jquery为主,很多插件都是依赖于Jquery的,AngulaJS的插件少之又少(除了AngularUI其他的Angula

  • Spring的连接数据库以及JDBC模板(实例讲解)

    前言 今天介绍的是关于Spring的数据库连接以及Jdbc模板的相关API方法,虽然在学习了hibernate之后,会知道实现数据库连接一般都是使用hibernate等持久化框架来实现的.但是,很多时候一些涉及到事务的东西使用这些框架并不能够实现,所以我们还需要结合spring来实现相关的需要. 一.创建工程.导包 要想使用Spring的jdbc模板前,还需要导入相关的jar包: 二.进行相关的bean的创建以及工具类的编写 2.1在数据库中创建了两张表,使用spring的jdbcTemplat

  • 在Django框架中自定义模板过滤器的方法

    自定义过滤器就是有一个或两个参数的Python函数: (输入)变量的值 参数的值, 可以是默认值或者完全留空 例如,在过滤器 {{ var|foo:"bar" }} 中 ,过滤器 foo 会被传入变量 var 和默认参数 bar. 过滤器函数应该总有返回值. 而且不能触发异常,它们都应该静静地失败. 如果出现错误,应该返回一个原始输入或者空字符串,这会更有意义. 这里是一些定义过滤器的例子: def cut(value, arg): "Removes all values o

  • MVC使用T4模板生成其他类的具体实现学习笔记2

    在前篇中我们已经将User类中的代码做了具体的实现,但仍然有多个实体类未实现,以后可能还会增加新的数据表,数据表结构也有可能发生变化,所以我们使用T4模板来完成类的生成,这样就算数据库表发生了改变,也会自动根据改变后的实体对类进行重新生成. 下面是数据访问层的T4模板文件 Dal.tt <#@ template language="C#" debug="false" hostspecific="true"#> <#@ inclu

随机推荐