template模板:泛型化编程

2023-10-29

一.在函数中使用模板:

template <typename形参1,typename形参2> int compare(const形参1&a,const形参2&b);

类格式为:

template <class 形参1> class YuTest
{
public:
	形参1 GetNum();
	……
}
注意:

1.每个模板形参都必须有关键字typenameclass来修饰。不可以漏写。

如:       template<typenameT,U> 的写法是错误的。

2.模板形参有两种:①类型化形参,该种形参接收一个类对象,可以用typenameclass来修饰;②非类型形参,或者说常量表达式形参,该种形参接收一个常量,可以用typenameclass来修饰。

typenameclass两个关键字的区别在于,class使用更早,故早期版本主要使用class

3.每个模板形参个数并非是任意定义的。一旦定义,后面的函数参数中或类的实现中就必须要用到,否则会编译出错。

4.多个模板形参的名称必须不同。如:template <typenameT,typename T>这样的写法是错误的

4.每个template只对其后的一个函数或类起作用

5.模板类的声明和实现就目前的编译器而言,必须都在h文件里写。无论是模板类型还是模板函数都是如此。若是模板类,则其成员函数实现也都要在.h中实现。

6.模板函数定义与模板类型方式相同。使用的时候当做一个正常的函数直接调用函数名即可,无需其他操作

template <class T>
int f(T t)
{
	return t + 1;
}
然后直接可以:

cout<<f(10)<<endl;

其输出值为11。

7.使用模板类必须显示地为模板形参指定参数。

如上面的YuTest,需要这样调用:YuTest<int>m_yuTest;或YuTest<CString>m_yuTest;

 

技巧:使用关键字typedef为每一个类型定义一个别名,使用时直接引用别名。

typedef  YuPointT<int>     YuPoint;

 

二.在类中使用template,有两种方式:

①类中有多个成员函数及成员变量是template类型,那么该类就称之为模板类,需要在类定义前加template <typename形参1>

template <class 形参1>
class YuTest
{
public:
	形参1 GetNum();
	……
}
实现:

template<typename形参1>	YuTest <形参1>::GetNum()
{
}

②类中只有1个成员函数是template类型,那么只需要在函数前加template <typename形参1>即可:

class YuTest
{
public:
	template <class T>
	T  GetNum(T p1);
	……
}
实现:

template<typename T >	YuTest < T >::GetNum()
{
}

三. template 的编译是直到调用时才进行的

       编译器在遇到template的实现时并不为其产生机器代码,而是等到template被指定某种类型时才会编译。

       因此,以下调用是合法的:

class A
{
public:
	A() { x = 1; }
	int x;
};

class B
{
public:
	B() { x = 2.0; }
	double x;
};

class C
{
public:
	C() { x = 3.0; }
	float x;
};

template <class T>
int f(T t)
{
	int a;
	k = (int)t.x;//注①特别注意这里,见下文解释
	return k;
}

void main()
{
	A a;
	B b;
	C c;

	cout << f(a) << endl;
	cout << f(b) << endl;
	cout << f(c) << endl;
}
 如上,一般来说, template所指定的类型 T可以是任何类型。直接使用该类型是可以的。但调用一个未知类型的成员变量或者成员函数是否也可以?

       就如同注①那样,函数f()传入的参数是一个未知类型T,但在函数内却使用了的成员变量x。但T的类型未知,编译器如何知道该类型内是否有成员变量x?

       首先,这样使用是合法的。对于上面的程序而言,编译也会通过并顺利运行。

       其原因就是编译器在遇到template的实现时并不为其产生机器代码,而是等到template被指定某种类型时才会编译。当在main()中运行cout<<f(a)<<endl;时,就会把a赋给T,此时编译器便会编译一次f()的代码,用a将其中的T全部替换。编译f()中的k = (int)a.x;时,顺利通过。同理,运行cout<<f(b)<<endl;时,编译器会编译第二次f()的代码。整个程序结束,编译器会将f()编译三次。

       若将cout<<f(c)<<endl;改为cout<<f(9)<<endl;,当编译器通过了前两次f()的编译,来对该行代码进行编译时,发现其参数9是个int型,而int并无x成员变量,于是在编译k = (int)9.x;时就会出错。

       编写程序时,若需要使用以上的写法,无法使用自动补全功能,也就是靠使用”.”或者”->”是无法自动补全成员变量或成员函数的。因此需要手动填写。只要保证函数内所有涉及的操作在传入的参数类中均有实现即可。

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

template模板:泛型化编程 的相关文章

随机推荐

  • java Logback输出日志内容到文件

    要将logger info的信息输出到文件 您可以使用Logback配置 下面是一个简单的示例 1 首先 在您的项目中添加Logback依赖 例如在Maven项目中的pom xml文件中添加以下代码
  • 基于OpenCV的交通标志识别(SVM+Hu不变矩, 部分测试源代码)

    最近跟着老师做一个交通识别的项目 总算明白了一个道理 这水啊 不去亲自蹚上一遭就不知道有多深 更根本的原因当然还是自己学的不够扎实 不够好 经过了一个寒假的折磨 终于做出了一个原型来 想到了自己当时被折磨的头疼的样子 想着将一部分源代码发上
  • 前端post请求中body和query传参的区别

    前端发送请求最常用的是get请求还有post请求 get请求只能传query参数 query参数都是拼在请求地址上的 post可以传body和query两种形式的参数 如下 编辑项目列表 export function editProjec
  • SeqGPT: 开箱即用的开放域自然语言理解大模型

    论文链接 SeqGPT An Out of the box Large Language Model for Open Domain Sequence Understanding https arxiv org abs 2308 10529
  • 【DL】血与泪的炼丹心得

    记录一些炼丹的心得 都是坑啊 以下都是经过很多实验得到的炼丹心得 希望对大家有帮助 模型很复杂 各种网络融合 尝试用更小的学习率和更多的epoch 学习率预热是个好东西 必须用上 学习率很重要 可以发掘模型的极限 但是无法改变模型的上限 模
  • DataAnalysis-Maggie-Lecture6-机器学习基础

    ML的基础框架 1定义要解决的问题 2构建数据集 3数据变换 4训练模型 5使用模型预测 example 垃圾邮件标记系统来解释术语 Dataset 一堆的邮件 Sample Instances 一封邮件 Feature Variables
  • springcloud微服务:nacos的配置说明与服务注册

    这部分我要知道两点就是nacos如何去注册服务和发现服务的 一 工程结构和版本依赖 首先要说一个我们的springcloud工程 基于半仙的springcloud工程 这个工程比较有意思 就是我很少看到pom文件一层套一层 相当于是三级po
  • 修改el-card的header的背景颜色

    修改el card的header的背景颜色 1 修改默认样式 好处是当前页面的所有的el card都会变化 页面卡片
  • linux0.00 代码阅读笔记

    汇编语言的编写 编译 运行 调试 author hjjdebug date 参考代码地址 GitHub hjjdebug linux0 00 linux0 00 code compiled under ubuntu14 04 gcc 4 8
  • Vue3的基本语法及使用(vue3尚硅谷学习笔记)

    一 Vue3的基本语法及使用 1 Vue3的基本语法 1 1 初识setup setup是Vue3中一个新的配置项 值为一个函数 组件中所要用到的数据 方法等 均要配置在setup中 setup的两种返回值 若返回一个对象 则对象中的属性
  • QT编程常见崩溃问题总结

    一 主程序事件循环函数崩溃 a exec 处崩溃 该处崩溃一般调试的时候显示的堆栈信息停止的位置都是QT的dll库 我们的代码中只给出了a exec 崩溃 原因一 子线程中更改界面上控件 在Qt事件循环中一般只有主线程可以用来改变某一个显示
  • CFSum: A Coarse-to-Fine Contribution Network for MMS

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 作者 肖敏 朱军楠 林海涛 周玉 宗成庆 单位 中国科学院自动化研究所 邮箱 min xiao nlpr ia ac cn 1 摘要 多模式摘要通常存在一个问题 即视觉模态的贡献
  • 推荐10个堪称神器的 Java 学习网站

    经常有一些读者问我 二哥 学习 Java 应该关注哪些网站 我之前的态度一直是上知乎 上搜索引擎搜一下不就知道了 但读者对我这个态度很不满意 他们说 我在问你 又不是问知乎 问搜索引擎 你还别说 读者说得有道理 于是我想 那就推荐一些吧 先
  • 【人工智能

    一 什么是多模态 多模态 multimodal 是指涉及到多种模态 如视觉 语音 文本等 的数据或信息 在计算机科学和人工智能领域中 多模态通常指将多种类型的数据或信息相结合 来解决特定的问题或任务 以图像识别为例 图像可以被视为一种视觉模
  • 域中DC和AD的区别

    今天朋友问我DC和AD的区别时 我也是一脸懵X 所以我查了一些资料 做个小总结 域 我的理解是他就是一个架构 和工作组类似 和工作组最大的区别就是 工作组没有管理者 而域可以集中管理 再详细一点的解释就是在工作组上你一切的设置比如在本机上进
  • Vue引入并使用Element-UI组件库的两种方式

    前言 在开发的时候 虽然我们可以自己写css或者js甚至一些动画特效 但是也有很多开源的组件库帮我们写好了 我们只需要下载并引入即可 vue和element ui在开发中是比较般配的 也是我们开发中用的很多的 下面就介绍下如何在eue项目中
  • 博图db块变量导出_博途中,DB里定义的变量的改变

    问题描述 1 新的博途中 生成一个全局DB 打开 在第一行自动生成了 名称 为static的变量 名称无法修改 数据类型无法选择 而在老版的STEP7里 分明是一个无名称 数据类型是STRUCT 无法重新选择 的变量 为什么做了这样的改变
  • 理解super().__init__()

    目录 一 写在前面 本文仅为个人的理解 如有错误欢迎指正 二 super init 的含义 三 代码实验 四 理解super init 五 Reference 一 写在前面 本文仅为个人的理解 如有错误欢迎指正 二 super init 的
  • AdaGrad(自适应梯度算法),Adaptive

    学习衰减率 随着学习的进行 使得学习率逐渐减小 AdaGrad会为参数的每个元素适当的体哦阿正学习率 coding utf 8 import numpy as np class AdaGrad def init self learning
  • template模板:泛型化编程

    一 在函数中使用模板 template