【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?

这篇具有很好参考价值的文章主要介绍了【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1 -> 泛型编程

2 -> 函数模板

2.1 -> 函数模板概念

2.2 -> 函数模板格式

2.3 -> 函数模板的原理

2.4 -> 函数模板的实例化

2.5 -> 函数参数的匹配原则

3 -> 类模板

3.1 -> 类模板的定义格式

3.2 -> 类模板的实例化


【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

1 -> 泛型编程

怎样实现一个通用的交换函数?

#include <iostream>
using namespace std;

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;
}

int main()
{
	int a = 1;
	int b = 2;

	Swap(a, b);

	cout << a << " " << b << endl;

	double x = 1.2;
	double y = 2.4;

	Swap(x, y);

	cout << x << " " << y << endl;

	return 0;
}

使用函数重载虽然可以实现,但是有几个不好的地方:

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现,就需要用户自己增加对应的函数;
  2. 代码的可维护性比较低,一个出错可能所有重载都出错。

那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

活字印刷术是一种用雕刻或铸造金属或木头字形,然后用墨水涂抹字形再用压力印在纸张上的印刷技术。

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

如果在C++中,也能够存在这样一个模具,通过给这个模具中填充不同字形(类型),来获得不同字形的文章(即生成具体类型的代码)。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

2 -> 函数模板

2.1 -> 函数模板概念

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

2.2 -> 函数模板格式

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

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

#include <iostream>
using namespace std;

template<typename T>

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

int main()
{
	int a = 1;
	int b = 2;

	Swap(a, b);

	cout << a << " " << b << endl;

	double x = 1.2;
	double y = 2.4;

	Swap(x, y);

	cout << x << " " << y << endl;

	return 0;
}

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

注意:

typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)。

#include <iostream>
using namespace std;

template<class T>

T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	cout << Add(1, 2) << endl;

	return 0;
}

2.3 -> 函数模板的原理

函数模板就是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

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

2.4 -> 函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:

  1. 隐式实例化:让编译器根据实参推演模板参数的实际类型。
  2. 显式实例化:在函数名后的<>中指定模板参数的实际类型。
#include <iostream>
using namespace std;

template<class T>

T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	cout << Add(1, 2) << endl;

	/*该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型
	通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,
	编译器无法确定此处到底该将T确定为int 或者 double类型而报错
	注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅*/
	//cout << Add(1.1, 2) << endl;
	// 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化

	cout << Add((int)1.1, 2) << endl;
	cout << Add(1.1, (double)2) << endl;

	// 显示实例化
	cout << Add<int>(1.1, 2) << endl;
	cout << Add<double>(1.1, 2) << endl;

	return 0;
}

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

2.5 -> 函数参数的匹配原则

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。

#include <iostream>
using namespace std;

// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}

// 通用加法函数
template<class T>

T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	// 与非模板函数匹配,编译器不需要特化
	cout << Add(1, 2) << endl;

	// 调用编译器特化的Add版本
	cout << Add((int)1.1, 2) << endl;

	return 0;
}

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个示例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板。

#include <iostream>
using namespace std;

// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}

// 通用加法函数
template<class T>

T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	// 与非函数模板类型完全匹配,不需要函数模板实例化
	cout << Add(1, 2) << endl;

	// 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
	cout << Add(1, 2.0) << endl;

	return 0;
}

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?,C++,c++,开发语言,visualstudio,后端

3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

3 -> 类模板

3.1 -> 类模板的定义格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{
 // 类内成员定义
};
#include <iostream>
using namespace std;

// 动态顺序表
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>

class Vector
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}

	// 使用析构函数演示:在类中声明,在类外定义。
	~Vector();

	void PushBack(const T& data);

	void PopBack();

	size_t Size() 
	{ 
		return _size; 
	}

	T& operator[](size_t pos)
	{
		assert(pos < _size);
		return _pData[pos];
	}

private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};

// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>

Vector<T>::~Vector()
{
	if (_pData)
		delete[] _pData;

	_size = _capacity = 0;
}

3.2 -> 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

// Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;

感谢各位大佬支持!!!

互三咯!!!文章来源地址https://www.toymoban.com/news/detail-829578.html

到了这里,关于【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++航海王:追寻罗杰的编程之路】string类

    目录 1 - 为什么学习string类? 1.1 - C语言中的字符串 2 - 标准库中的string类 2.1 - string类 2.2 - string类的常用接口 3 - string类的模拟实现 3.1 - 经典的string类问题 3.2 - 浅拷贝  3.3 - 深拷贝 3.3.1 - 传统写法的string类 3.3.2 - 现代写法的string类 3.4 - 写时拷贝 3.5 - string类的模拟实现 在C语言

    2024年02月21日
    浏览(40)
  • 【C++航海王:追寻罗杰的编程之路】C++的类型转换

    目录 1 - C语言中的类型转换 2 - 为什么C++需要四种类型转换 3 - C++强制类型转换 3.1 - static_cast 3.2 - reinterpret_cast 3.3 - const_cast 3.4 - dynamic_cast 4 - RTTI 在C语言中,如果 赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需

    2024年04月13日
    浏览(36)
  • 【C++航海王:追寻罗杰的编程之路】C++11(上)

    目录 1 - C++11简介 2 - 统一的列表初始化 2.1 - {}初始化 2.2 - std::initializer_list 3 - 声明 3.1 - auto 3.2 - decltype 3.3 - nullptr 在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了 C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中

    2024年04月23日
    浏览(33)
  • 【C++航海王:追寻罗杰的编程之路】C++11(中)

    目录 C++11(上) 1 - STL中的一些变化 2 - 右值引用和移动语义 2.1 - 左值引用和右值引用 2.2 - 左值引用与右值引用比较 2.3 - 右值引用使用场景与意义  2.4 - 右值引用引用左值及其更深入的使用场景分析 2.5 - 完美转发 新容器 圈起来的是C++11中的一些几个新容器,但是实际最有用的

    2024年04月24日
    浏览(39)
  • 【C++航海王:追寻罗杰的编程之路】探寻实用的调试技巧

    目录 1 - 什么是bug? 2 - 调试是什么?有多重要? 2.1 - 调试是什么? 2.2 - 调试的基本步骤 2.3 - Debug和Release的介绍 3 - Windows环境调试介绍 3.1 - 调试环境的准备 3.2 - 学会快捷键 3.3 - 调试的时候查看程序当前信息 3.3.1 - 查看临时变量的值 3.3.2 - 查看内存信息 3.3.3 - 查看调用堆栈

    2024年04月12日
    浏览(39)
  • 【C++航海王:追寻罗杰的编程之路】继承你学会了么?

    目录 1 - 继承的概念及定义 1.1 - 继承的概念 1.2 - 继承的定义 1.2.1 - 定义格式 1.2.2 - 继承关系和访问限定符 1.2.3 - 继承基类成员访问方式的变化 2 - 基类和派生类对象赋值转换 3 - 继承中的作用域 4 - 派生类的默认成员函数 5 - 继承与友元 6 - 继承与静态成员 7 - 复杂的菱形继承及

    2024年04月16日
    浏览(41)
  • 【C++】关于多线程,你应该知道这些

    thread类的简单介绍 在 C++11 之前,涉及到多线程问题,都是和平台相关的,比如 Windows 和 Linux 下各有自己的接口,这使得代码的可移植性比较差。C++11 中最重要的特性就是对线程进行支持了,使得 C++ 在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概

    2023年04月15日
    浏览(50)
  • 20年编程,AI编程6个月,关于Copliot辅助编码工具,你想知道的都在这里

    AI代码辅助工具 尝试各种辅助编程的AI工具 笔者是一个后端Coder~,开发工具使用Idea和VsCode。在过去我一直尝试找到一款适合自己的智能代码辅助工具,来告别繁琐的重复性编码,好提高开发效率。直到AIGC和AI Agent的迅速发展,越来越多的AI编码辅助工具百花齐放。宣告天下

    2024年04月08日
    浏览(46)
  • [C++历练之路]C++模板还能这么玩,已经走了好多弯路,后悔没有早点学会到。

    W...Y的主页 😊  代码仓库分享💕    🍔前言:  在C++的世界里,模板是一种强大而神奇的工具,宛如编程的瑰宝匣,蕴藏着无限的可能性。它们不仅能够让我们编写通用的代码,还能够在编译时实现类型安全的抽象。然而,模板的奥秘并非易见,它们像是编码世界中的魔法

    2024年02月04日
    浏览(40)
  • 关于模板的大致认识【C++】

    函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器 在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包