【C++】模板初阶

2023-11-17


1.文件的编译和链接

1.1编译

编译过程分为预处理、编译、汇编三个阶段。

预处理

预处理包括宏替换,删除注释,头文件展开,条件编译等操作。最后生成(.i)文件

编译

编译过程包括语法分析,词法分析,语义分析,符号汇总等过程。将编程语言转化为汇编代码,最后生成(.s)文件。

汇编

汇编过程包括汇总符号表,并将汇编代码转换为二进制的机器指令,最后生成(.o)文件。

1.2链接
  • 合并段表。
  • 符号表的合并和符号表的重定位。其中大部分的编译错误都是因为符号表出现了问题。
  • 链接过程将所有的(.o)文件和静态库链接在一起。

2.函数模板

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

2.1函数模板格式

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

template<class T>
void Swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	Swap(a, b);
	return 0;
}

image-20220602233134221

**查看汇编代码 **

模板实例化了一个Swap< int >函数

自定义类型使用函数模板

class tmp
{
public:
	 tmp (int aa = 1, int bb = 1)
		:_aa(aa)
		, _bb(bb)
	{}
	 tmp operator+(tmp& m)
	 {
		tmp t;
		t._aa = _aa + m._aa;
		t._bb = _bb + m._bb;
		return t;
	 }
private:
	int _aa;
	int _bb;
};
template<class T>
T add(T& a, T& b)
{
	return a + b;
}
int main()
{
	tmp m(2, 3);
	tmp n(2, 1);
	tmp res = add(m, n);
	return 0;
}

image-20220603005632436

2.2函数模板的显示实例化
template<class T>
T Add(const T&left,const T&right)
{
    return left+right;
}
int main()
{
    int a=10;
    double d1=20.0;
    Add<int>(a,b);
    return 0;
}
2.3非模板函数和同名函数模板的调用顺序

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

image-20220603010938898

3.类模板

template<class T>
class Vector {
public:
	Vector(int capacity = 10, int size = 0)
		:_a(new T[capacity])
		, _capacity(capacity)
		, _size(size)
	{}

	~Vector();
	void Pushback(const T& m);
	void Popback();
	T& operator[](int pos)
	{
		return _a[pos];
	}
private:
	T* _a;
	int _capacity;
	int _size;
};
template
class Vector<int>;
template<class T>
Vector<T>::~Vector() {
	if(_a)
		delete[] _a;
	_capacity = _size = 0;
}
int main()
{
	Vector<int>v(10, 0);
	return 0;
}

类模板的实例化与函数模板实例化不同,类模板实例化需要在类模板名字后面加上<实例化类型>

类模板中函数放在类外进行定义时,需要加模板参数列表

template<class T1,class T2,class T3......>
Vector<T1,T2,T3.....>::~Vector() {
	if(_a)
		delete[] _a;
	_capacity = _size = 0;
}

4.模板声明和定义分离的情况

模板不支持声明和定义放到两个文件中的。会出现链接错误

方法一:将模板的定义和声明放在,hpp文件下

template<typename T>
void Swap(T& left, T& right);

template<class T>
class Vector
{
public:
	Vector(size_t capacity = 10);
	void PushBack(const T& x);
private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};
//定义
template<typename T>
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
template<class T>
Vector<T>::Vector(size_t capacity)
	: _pData(new T[capacity])
	, _size(0)
	, _capacity(capacity)
{}

template<class T>
void Vector<T>::PushBack(const T& x)
{
	// ...
}

方法二:将需要使用的函数和类都进行实例化

#include "template.h"
template
void Swap<int>(int& left, int& right);
template
class Vector<int> ;
template
class Vector<double> ;

模板声明和定义不能放在两个文件的原因

首先需要明确,链接就是要找到函数,类等的地址。而对于模板来说,仅仅是提供一个范式,并没有在内存中开辟空间,所以也没有相应的地址。

如果定义和声明分开,在链接汇总符号表时,无法找到函数模板和类模板对应的地址,所以会出现链接错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】模板初阶 的相关文章

  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • (c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换

    目录 1 写一个宏实现offsetof 1 1 offsetof是什么 1 2 模拟实现offsetof 1 思路 2 代码 2 写一个宏实现整数二进制奇偶位交换 思路 代码 总结 1 写一个宏实现offsetof 1 1 offsetof
  • Android 内存泄漏的常见原因及其对应的解决方案

    Android 内存泄漏 Android应用程序中常见的内存泄漏原因有很多 以下是一些常见的原因及对应的解决方案 1 静态引用导致的内存泄漏 静态变量持有对Activity或Fragment的引用 导致它们无法被垃圾回收机制释放 解决方案
  • LogisticRegression

    1 概述 在scikit learn中 与逻辑回归有关的主要是这3个类 LogisticRegression LogisticRegressionCV 和logistic regression path 其中LogisticRegressi
  • 11个优秀的Android开发开源项目

    一 一个类似微信的时光轴效果 项目地址 https github com ljtyzhr TimeLine 二 安卓选择器类库 包括日期 时间 单项 双项选择器 城市地址选择器 项目地址 https github com gzu liyuj
  • hbase hbck工具

    fix Try to fix region assignments This is for backwards compatiblity fixAssignments Try to fix region assignments Replac
  • 网络视频刷单调查:4分钟免费刷2.2万300元能买4000万点击

    新生事物的起步常伴随着混沌期的野蛮生长 比如网络视频行业 如果说票房测量电影市场的高低 收视率检验电市场的冷暖 那么反映网络视频是否受欢迎的一个直观指标就是点击量了 公众所看到的视频点击量数据真实性到底如何 又有多少点击量是靠 刷单 刷出来
  • 掌握Python的X篇_23_main的作用(python规范写代码中,__name__内置变量的使用)

    上篇我们介绍了模块和如何使用模块 本篇将会介绍与模块共同会出现的问题 那就是在python规范写代码中会使用到 name 这种特殊的变量 文章目录 1 name 是什么 2 模块import的不方便 3 name 的用处 大家可能已经见过
  • 聚焦Web前端安全:最新揭秘漏洞防御方法

    在 Web 安全中 服务端一直扮演着十分重要的角色 然而前端的问题也不容小觑 它也会导致信息泄露等诸如此类的问题 在这篇文章中 我们将向读者介绍如何防范Web前端中的各种漏洞 万字长文 请先收藏再阅读 首先 我们需要了解安全防御产品已经为我
  • 【StyleGAN论文精读CVPR_2019】A Style-Based Generator Architecture for Generative Adversarial Networks

    StyleGAN论文精读CVPR 2019 A Style Based Generator Architecture for Generative Adversarial Networks 一 前言 Abstract 1 Introduct
  • 6-5抽象类和抽象方法的使用

    package com atguigu java abstract 关键字的使用 1 abstract 抽象的 2 abstract 可以用来修饰的结构 类 方法 3 abstract 修饰类 抽象类 此类不能实例化 抽象类中一定有构造器便
  • Makefile学习3

    addprefix函数 函数名称 加前缀函数 addprefix 返回值 以单空格分割的添加了前缀 PREFIX 的文件名序列 示例 addprefix src foo bar 回值为 src foo src bar wildcard即通配
  • 【网络协议详解】——数据链路层协议(学习笔记)

    前言 数据链路层是 OSI 模型中的第二层 位于物理层之上 是通信网络中的重要组成部分之一 数据链路层协议负责将网络层传输的数据分组封装成帧 传输到物理层 并通过物理介质进行传输 同时 数据链路层协议还需要提供错误检测和纠正 流控等功能 以
  • Android 使用高德SDK编写周边搜索定位

    转载请注明 前言 使用高德SDK实现定位及周边的搜索界面 先看效果图 效果图看这 传不上 使用到了高德以下sdk com amap api 3dmap latest integration com amap api search lates
  • 解决IDEA导入MAVEN项目,jar包没有引进来报Cannot resolve symbol 'Autowired'

    解决IDEA导入MAVEN项目 jar包没有引进来报Cannot resolve symbol Autowired 原因 IDEA的缓存导致 解决办法 找到项目所在文件夹 找到 idea文件夹 删掉 从新导入 就好了
  • Web后端开发(请求响应)上

    请求响应的概述 浏览器 请求 lt HTTP协议 gt 响应 Web服务器 请求 获取请求数据 响应 设置响应数据 BS架构 浏览器 服务器架构模式 客户端只需要浏览器 应用程序的逻辑和数据都存储在服务端 维护方便 体验一般 CS架构 客户
  • Navicat15工具连接PostgreSQL15失败

    1 错误现象及原因 错误现象 错误原因 postgresql 15版本中 pg database 系统表把 datlastsysoid 列删除了 所以造成了此错误 2 解决方法 1 将Navicat工具更新到官网最新版本 2 更换 post
  • uboot SPL framework的前世今生

    一开始只有uboot 没有SPL 后来由于一些原因 参考文献1 有些公司如TI添加了SPL 模块 SPL的作用为 参考文献2 为了提高代码的可重用性 uboot 2012 10中将SPL模块标准化 叫做SPL framework 查看ubo
  • 双指针技巧总结

    一 双指针技巧 情景1 通常 我们只需要一个指针进行迭代 即从数组中的第一个元素开始 最后一个元素结束 然而 有时我们会使用两个指针进行迭代 双指针的典型场景 1 从两端向中间迭代数组 2 一个指针从头部开始 而另一个指针从尾部开始 1 反
  • python获取最大、最小值

    1 获取数组极值 并返回索引 c 10 5 0 5 3 10 15 20 25 print c index min c 返回最小值 print c index max c 返回最大值 2 对series求最值 file path D Rec
  • 【C++】模板初阶

    文章目录 1 文件的编译和链接 1 1编译 1 2链接 2 函数模板 2 1函数模板格式 2 2函数模板的显示实例化 2 3非模板函数和同名函数模板的调用顺序 3 类模板 4 模板声明和定义分离的情况 1 文件的编译和链接 1 1编译 编译