iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++模板的特化超详细精讲
  • 416
分享到

C++模板的特化超详细精讲

C++模板特化C++模板函数特化 2022-11-13 14:11:54 416人浏览 安东尼
摘要

目录一、泛型编程二、函数模板2.1、函数模板的概念2.2、函数模板的格式2.3、函数模板的原理2.4、函数模板的实例化2.4.1、隐式实例化2.4.2、显示实例化三、类模板3.1、类

一、泛型编程

我们前面已经学过函数的重载,实现了在函数名相同的情况下,实现不同的功能!

例如:

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;
}
void Swap(char& left, char& right)
{
	char temp = left;
	left = right;
	right = temp;
}

利用函数重载虽然实现了“通用”的交换函数,但是会有以下问题:

  • 重载的函数仅仅是类型不同,代码复用率低,只要有新的类型时,有需要用户自己增加新的重载函数。
  • 代码的可维护性低,一个出错可能所有的重载都出错。

⭐️⭐️⭐️:在c++中是否存在一个模具,通过给这个模具中填充不同的材料(类型),来获得不同的铸件(即生成具体的代码)。

泛型编程:编写与类型无关的通用代码,是代码复用的一种的手段。模板是泛型编程的基础。

二、函数模板

2.1、函数模板的概念

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

2.2、函数模板的格式

template<typename T1, typename T2,…,typename Tn>

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

template<typename T>
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

⚠️注意:typename 是用来定义函数模板参数关键字的,也可以用class,但是不可以用struct。

2.3、函数模板的原理

函数模板我们可以理解为一个蓝图,它本身并不是函数,在编译器编译阶段根据传入的实参类型来推演生成对应类型的函数以供调用,也叫做函数模板的实例化。

2.4、函数模板的实例化

用不同类型的对象使用函数模板时,称为函数模板的实例化。模板参数实例化分为隐式实例化和显示实例化。

2.4.1、隐式实例化

让编译器根据实参推演模板参数的实际类型。

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main(){
	int a1 = 10, a2 = 20;
	double d1 = 10.0, d2 = 20.0;
	Add(a1, a2);
	Add(d1, d2);
	//Add(a1, d1);
	Add(a1, (int)d1);
	system("pause");
	return 0;
}

2.4.2、显示实例化

让函数名后的<>中指定模板参数的实际类型。

int main(){
	int a = 10;
	double b = 20.0;
	//Add(a, (int)b);//隐式
	Add<int>(a, b);//显示
	system("pause");
	return 0;
}

Add(a, b);目的在于如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

三、类模板

3.1、类模板的定义格式

template<typename T1, typename T2,…,typename Tn>

class 类模板名

{

//类内成员

};

3.1、类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化传的是类型,而函数模板实例化传的是对象,类模板实例化需要在类模板名字后面跟上<>,然后将实例化类型放在<>中即可!

vector<int> s1;

⚠️:与普通类不同,这里vector是类名,而vector才是类型。

四、模板的特化

4.1、概念

通常情况下,我们使用模板可以实现一些与类型无关的代码,但是对于一些特殊类型可能会得到一些错误的结果,需要特殊处理。

template<class T>
bool Less(T left, T right){
	return left < right;
}
//特化
template<>
bool Less<Date*>(Date* p1, Date* p2)
{
	cout << "调用的模板函数的特化" << endl;
	return *p1 < *p2;
}
//只要是指针  都可以调用这个,这个思想很重要
//偏特化的带限制条件(指针类型可调)
template<class T>
bool Less(T* left, T* right)
{
	cout << "调用的函数模板" << endl;
	return *left < *right;
}

代码解释:当我们在实参部分传的是Date型指针的时候,如果不特化处理,结果会出错。

上述就是在原模板的基础上针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化和类模板特化。

4.2、函数模板特化步骤

  • 必须要先有一个基础的函数模板。
  • 关键字template后面接一队空的<>。
  • 函数名后跟一对<>,尖括号中指定需要特化的类型。
  • 函数形参表:必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。
template<class T>
bool Less(T left, T right){
	return left < right;
}
//特化
template<>
bool Less<Date*>(Date* p1, Date* p2)
{
	cout << "调用的模板函数的特化" << endl;
	return *p1 < *p2;
}

4.3、类模板的特化

4.3.1、全特化

全特化就是将模板参数中所有的参数都确定化

//类模板
template<class T1, class T2>
class data
{
public:
	data(T1 a, T2 b)
		:_a(a)
		, _b(b)
	{
		cout << "data<T1, T2>" << endl;
	}
private:
	T1 _a;
	T2 _b;
};
//全特化
template<>
class data <int, char>
{
public:
	data(int a, char b)
		:_a(a)
		, _b(b)
	{
		cout << "全特化data<int, char>" << endl;
	}
private:
	int _a;
	char _b;
};
int main()
{
	data<int, int> s1(1, 2);
	data<int, char> s2(1, 'a');
}

4.3.2、偏特化

偏特化:任何针对模板参数进一步进行条件限制设计的特化版本。比如对一下类模板:

//类模板
template<class T1, class T2>
class data{
public:
	data(T1 a, T2 b)
		:_a(a)
		, _b(b)
	{
		cout << "data<T1, T2>" << endl;
	}
private:
	T1 _a;
	T2 _b;
};

⭐️⭐️⭐️偏特化有以下两种变现方式:

部分特化:将模板参数中的一部分参数特化

//半特化
// 1、将模板参数类表中的一部分参数特化。
template<class T1>
class data<T1, char> {
public:
	data(T1 a, char b)
		:_a(a)
		, _b(b)
	{
		cout << "偏特化data<T1, char>" << endl;
	}
private:
	T1 _a;
	char _b;
};

参数进一步限制:偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的特化版本。

// 2、偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
template<class T1, class T2>
class data <T1*, T2* > {
public:
	data(T1 a, char b)
		:_a(a)
		, _b(b)
	{
		cout << "Data<T1*, T2*>" << endl;
	}
private:
	T1 _a;
	T2 _b;
};
template<class T1, class T2>
class data<T1&, T2&>
{
public:
	data(const T1& a, const T2& b)
		:_a(a)
		, _b(b)
	{ cout << "Data<T1&, T2&>" << endl; }
private:
	const T1& _a;
	const T2& _b;
};
int main(){
	data<char*, char*> s6(1,2);
	data<int&, int&> s7(1, 2);
	system("pause");
	return 0;
}

代码解释:

  • 第一个是两个参数特例化为指针类型(只要传的是指针,就走对应的)。
  • 第二个是两个参数特例化为引用类型。

到此这篇关于C++模板的特化超详细精讲的文章就介绍到这了,更多相关C++模板特化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++模板的特化超详细精讲

本文链接: https://www.lsjlt.com/news/171678.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++模板的特化超详细精讲
    目录一、泛型编程二、函数模板2.1、函数模板的概念2.2、函数模板的格式2.3、函数模板的原理2.4、函数模板的实例化2.4.1、隐式实例化2.4.2、显示实例化三、类模板3.1、类...
    99+
    2022-11-13
    C++ 模板特化 C++ 模板函数特化
  • C++超详细讲解模板的使用
    目录一、函数模板1.1函数模板概念1.2 函数模板格式1.3 函数模板的原理1.4 函数模板的实例化二、类模板2.1 类模板的定义格式2.2类模板的实例化总结一、函数模板 1.1函数...
    99+
    2024-04-02
  • C++BoostGraph算法超详细精讲
    Boost.Graph 中的算法类似于标准库中的算法——它们是通用的并且非常灵活。但是,并不总是很清楚应该如何使用它们。 示例 31.8。使用breadth_...
    99+
    2022-11-13
    C++ Boost Graph C++ Boost Graph算法
  • C++BoostAlgorithm算法超详细精讲
    目录一、说明Boost.Algorithm二、示例练习一、说明Boost.Algorithm Boost.Algorithm 请注意,其他 Boost 库提供了许多算法。例如,您会在...
    99+
    2022-11-13
    C++ Boost Algorithm C++ Boost Algorithm算法
  • C++ Boost CircularBuffer算法超详细精讲
    提要 库 Boost.CircularBuffer 提供了一个循环缓冲区,它是一个具有以下两个基本属性的容器: 循环缓冲区的容量是恒定的,由您设置。当您调用成员函数(例如 push_...
    99+
    2022-11-13
    C++ Boost CircularBuffer Boost.CircularBuffer C++ CircularBuffer
  • C++超详细介绍模板
    目录定义例子格式处理方法定义 函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。 ...
    99+
    2024-04-02
  • C++模板超详细介绍
    目录1.前言2.函数模板3.类模板1.前言 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。 模板是创建泛型类或函数的蓝图或公式。 通常有两种形式:函数模板和...
    99+
    2024-04-02
  • SpringCloudOpenFeign超详细讲解模板化远程通信的实现
    目录1. openFeign实现1.1 pom依赖1.2 yaml配置1.3 客户端调用代码1.4.服务端暴露接口1.5.测试日志1. openFeign实现 基于spring-bo...
    99+
    2024-04-02
  • SpringBoot超详细讲解Thymeleaf模板引擎
    Jsp是最早的模板技术,用来处理视图层的,用来做数据显示的模板 B S结构: B:浏览器:用来显示数据,发送请求,没有处理能力 发送一个请求,访问a.jsp,a.jsp在服务器端变...
    99+
    2024-04-02
  • C++中的模板特化与模板偏特化?
    模板特化和偏特化是 c++++ 中的特有机制。模板特化可为特定类型的模板参数提供特定实现,而模板偏特化则允许根据部分模板参数类型化模板,使使用更灵活。模板特化使用 template 语法...
    99+
    2024-05-08
    c++ 模板 特化
  • C++类模板与函数模板基础详细讲解
    目录函数模板类模板总结函数模板 当我们想要定义一个可以支持泛型的函数时,就要采用函数模板的方式了。所谓泛型就是可以支持多种类型的操作,比如我们定义一个compare操作,他可以根据传...
    99+
    2022-11-13
    C++类模板 C++函数模板
  • C++超详细讲解模拟实现vector
    目录1. 模拟实现vector2. vector常用接口2.1 reserve2.2 resize2.3 push_back2.4 pop_back()2.5 insert2.6 e...
    99+
    2024-04-02
  • C++BoostUuid超详细讲解
    目录一、说明二、Boost.Uuid库示例和代码一、说明 Boost.Uuid 为 UUID 提供生成器。 UUID 是不依赖于中央协调实例的通用唯一标识符。例如,没有数据库存储所有...
    99+
    2022-12-08
    C++ Boost Uuid C++ Uuid标识符
  • C++模板非类型形参的详细讲解
    前言 关于模板的非类型形参,网上有很多内容,C++primer只有大概一页的阐述,但是都不够清晰详细。下面我尽可能从自己的角度去给大家描述一下非类型形参的相关细节。如果想进一步理解非...
    99+
    2024-04-02
  • C++BoostUtility超详细讲解
    目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速...
    99+
    2022-12-08
    C++ Boost Utility C++ Utility库
  • C++可扩展性与多线程超详细精讲
    目录一、可扩展性和多线程二、线程示例一、可扩展性和多线程 基于 Boost.Asio 之类的库开发程序与通常的 C++ 风格不同。可能需要更长时间才能返回的函数不再按顺序调用。 Bo...
    99+
    2022-11-13
    C++可扩展性与多线程 C++多线程 C++可扩展性
  • ReactRenderProps模式超详细讲解
    目录正文使用Render Props来完成关注点分离render prop的prop名不一定叫render注意点render prop是一个技术概念。它指的是使用值为function...
    99+
    2022-11-16
    React RenderProps React RenderProps模式
  • VueMVVM模型超详细讲解
    目录理解MVVM模型什么是 MVVM 模型MVVM的组成部分Vue中的实现MVVM模型在Vue中的应用理解MVVM模型 我们知道每一个 Vue 应用都是从创建一个新的实例开始的,根据...
    99+
    2022-11-13
    Vue MVVM模型 Vue MVVM框架
  • Python模板的使用详细讲解
    目录一 模板语法传值二 过滤器三 标签四 自定义模板标签和过滤器4.1 自定义过滤器4.2 自定义标签函数4.3 自定义inclusion_tag五 模板的继承六 模板的导入一 模板...
    99+
    2024-04-02
  • Java BOI与NIO超详细实例精讲
    目录Java BIO示例代码Java NIO代码解读Java BIO 阻塞IO,每个客户端链接都需要一个独立的线程处理,客户端链接没关闭时,线程链接处于阻塞状态,直到客户端链接关闭 ...
    99+
    2022-11-16
    Java BOI与NIO Java NIO Java BOI
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作