第八层:模板(中)

简介: 第八层:模板(中)

函数模板产生更好的匹配时


当普通函数要发生类型转换,但模板可以直接调用的时候,就会调用函数模板

#include<iostream>
using namespace std;
template<typename T>
void print(T a, T b)
{
  cout << "调用函数模板" << endl;
}
void print(int a, int b)
{
  cout << "调用普通函数" << endl;
}
void test1()
{
  char a = 0;
  char b = 0;
  print(a, b);
}
int main()
{
  test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png

这个时候如果时调用普通函数,就会发生隐式类型调用,这个时候用函数模板就不需要,就调用函数模板。


模板的局限性


模板的通用性不是万能的,比如要进行交换操作的时候,如果传参的是数组或者对象的时候,可以调用吗?

#include<string>
#include<iostream>
using namespace std;
template<typename T>
void Swap(T &a, T &b)
{
  T tmp = a;
  a = b;
  b = tmp;
}
class A
{
public:
  A(string a, int b)
  {
  _name = a;
  _age = b;
  }
  string _name;
  int _age;
};
void test1()
{
  A c1("zhangsan", 19);
  A c2("lisi",20);
  Swap(c1, c2);
  cout << c1._name << "的年龄" << c1._age << endl;
  cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
  test1();
  return 0;
}

0eacb84100b54626af849e6b562bf92a.png

发现并不能实现交换,那对于这些特殊的类型,怎么才可以进行呢?操作符重载吗?试一试:


#include<string>
#include<iostream>
using namespace std;
class A
{
public:
  A(string a, int b)
  {
  _name = a;
  _age = b;
  }
  void operator=(A& a)
  {
  _name =a._name;
  _age = a._age;
  }
  string _name;
  int _age;
};
template<typename T>
void Swap(T &a, T &b)
{
  T tmp = a;
  a = b;
  b = tmp;
}
void test1()
{
  A c1("zhangsan", 19);
  A c2("lisi", 20);
  Swap(c1, c2);
  cout << c1._name << "的年龄" << c1._age << endl;
  cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
  test1();
  return 0;
}

2d65d23f6d4748949b924e4057485923.png

操作符重载是可以的,那还有没有方法呢?这个时候可以具体化一个类的版本实现,这个时候具体化是优先调用的,那具体化的语法是什么呢?语法:


template< > 返回类型 函数模板名 (参数的数据类型为类名)

#include<string>
#include<iostream>
using namespace std;
template<typename T>
void Swap(T& a, T& b)
{
  T tmp = a;
  a = b;
  b = tmp;
}
class A
{
public:
  A(string a, int b)
  {
  _name = a;
  _age = b;
  }
  string _name;
  int _age;
};
template< > void Swap(A& c1, A& c2)
{
  string tmp1 = c1._name;
  c1._name = c2._name;
  c2._name = tmp1;
  int tmp2 = c1._age;
  c1._age = c2._age;
  c2._age = tmp2;
}
void test1()
{
  A c1("zhangsan", 19);
  A c2("lisi", 20);
  Swap(c1, c2);
  cout << c1._name << "的年龄" << c1._age << endl;
  cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
  test1();
  return 0;
}

2e9b90b2ca334476abebe75bafe6eeaa.png

也是可以实现。


类模板


作用


建立一个通用类,类内成员的数据类型不可具体定义,用一个通用的类型来代表


语法


那类模板的语法是什么?语法如下:


template< typename T>

因为类内会有多个数据类型,可以定义多个通用的数据类型,那尝试写一个类模板出来:


#include<iostream>
using namespace std;
template<typename T1, typename T2>
class A
{
public:
  T1 _a;
  T2 _b;
};
int main()
{
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png

是可以正常跑起来的,那怎么使用这个类模板实例化一个对象出来呢?


类模板实例化对象


实例化对象的语法:


类名< 数据类型(为模板参数列表) > 对象名

那选择通过一个类模板实例化出一个对象:


#include<iostream>
using namespace std;
template<typename T1, typename T2>
class A
{
public:
  T1 _a;
  T2 _b;
};
void test1()
{
  A<int, char> a1;
  a1._a = 10;
  a1._b = 'a';
  cout << a1._a << endl;
  cout << a1._b << endl;
}
int main()
{
  test1();
  return 0;
}

0eacb84100b54626af849e6b562bf92a.png


类模板与函数模板的区别


1.类模板没有自动类型推导的使用方式

2.类模板在模板参数列表中可以具有默认参数

自动类型推导验证

#include<iostream>
using namespace std;
template<typename T1, typename T2>
class A
{
public:
  T1 _a;
  T2 _b;
};
void test1()
{
  A< > a1;
  a1._a = 10;
  a1._b = 'a';
  cout << a1._a << endl;
  cout << a1._b << endl;
}
int main()
{
  test1();
  return 0;
}

2d65d23f6d4748949b924e4057485923.png

报错了,跑不起来,是不可以用的。


类模板参数列表中可以具有默认参数

这个是什么意思呢?这里用代码证明:


#include<iostream>
using namespace std;
template<typename T1=int, typename T2=char>
class A
{
public:
  T1 _a;
  T2 _b;
};
void test1()
{
  A< > a1;
  a1._a = 10;
  a1._b = 'a';
  cout << a1._a << endl;
  cout << a1._b << endl;
}
int main()
{
  test1();
  return 0;
}

2e9b90b2ca334476abebe75bafe6eeaa.png

这个代码和上面的代码的区别在哪?

4cebaac233b3433da32a72337a77fc60.png

看到,在模板的参数列表中,给通用数据类型进行了赋值,让它具有了默认数据类型,这个时候就可以在实例化对象的时候,不用写数据类型,用默认的数据类型,也可以在改数据类型:


#include<string>
#include<iostream>
using namespace std;
template<typename T1=int, typename T2=char>
class A
{
public:
  T1 _a;
  T2 _b;
};
void test1()
{
  A<double,string > a1;
  a1._a = 10.0;
  a1._b = "abcd";
  cout << a1._a << endl;
  cout << a1._b << endl;
}
int main()
{
  test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png


类模板中成员函数的创建时机


普通类的成员函数会在一开始就创建,类模板中的成员函数在应用时才会创建,对于类模板中调用其他类的时候的成员函数,在确认数据类型前,可以进行编译,没有问题,但是否调用成功时在确定数据类型后


相关文章
C4.
|
缓存 Java
Java的Integer对象
Java的Integer对象
C4.
189 0
|
算法 索引
阿里云 Elasticsearch 使用 RRF 混排优化语义查询结果对比
Elasticsearch 从8.8版本开始,新增 RRF,支持对多种不同方式召回的多个结果集进行综合再排序,返回最终的排序结果。之前 Elasticsearch 已经分别支持基于 BM25 的相关性排序和向量相似度的召回排序,通过 RRF 可以对这两者的结果进行综合排序,可以提升排序的准确性。
3272 0
|
11月前
|
人工智能 API 数据库
Cognita:小白也能搭建 RAG 系统,提供交互界面的开源模块化 RAG 框架,支持多种文档检索技术
Cognita 是一个面向生产环境的开源模块化 RAG 框架,支持本地部署、无代码 UI 和增量索引,帮助开发者轻松构建和扩展生产级应用。
603 11
Cognita:小白也能搭建 RAG 系统,提供交互界面的开源模块化 RAG 框架,支持多种文档检索技术
|
9月前
|
机器学习/深度学习 运维 监控
万亿参数模型训练神器:Kubeflow 2025量子加速版下载与TPU集群配置详解
Kubeflow 2025 是一个云原生机器学习操作系统,实现了四大突破性创新:量子混合训练(支持经典-量子混合神经网络协同计算)、神经符号系统集成(融合深度学习与逻辑推理引擎)、边缘智能联邦(5G MEC节点自动弹性扩缩容)和因果可解释性框架(集成Pearl、DoWhy等工具链)。该平台通过混合计算架构、先进的硬件配置矩阵和量子增强型安装流程,提供了从基础设施预配置到核心组件安装和安全加固的完整部署方案。此外,Kubeflow 2025 还涵盖全生命周期开发实战案例、智能运维监控体系、安全与合规框架以及高阶调试技巧,帮助用户高效构建和管理复杂的机器学习项目。
|
存储 弹性计算 缓存
阿里云服务器价格表参考,不同实例规格云服务器月付及年付活动价格(2024更新)
阿里云租服务器一年多少钱?不同时期阿里云服务器的租用价格不同,进入2024年,阿里云继续推出各种云服务器优惠政策,轻量应用服务器2核2G 61元1年,2核4G 165元1年;云服务器2核2G3M只要99元1年,2核4G5M只要199元1年;4核16G月付只要26.52元1个月。本文为大家整理汇总了目前阿里云的活动中,所有云服务器的月付及年付价格情况,以表格形式展示给大家,以供参考。
阿里云服务器价格表参考,不同实例规格云服务器月付及年付活动价格(2024更新)
动态颤抖的眼睛效果404页面源码
动态颤抖的眼睛效果404页面源码, 源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
122 1
动态颤抖的眼睛效果404页面源码
|
存储 安全 Java
深入理解Java内存模型(JMM)及其在并发编程中的应用
Java内存模型(JMM)是Java虚拟机规范中定义的一套规则,它指导着线程如何通过内存交互。JMM不仅关乎数据一致性与可见性问题,还直接影响到并发程序的正确性和性能。本文将探讨JMM的核心概念、工作原理及其在高效并发编程中的实践应用,旨在为读者提供一套完整的理论框架和实战技巧,以应对复杂并发环境下的挑战。
必知的技术知识:DoubleDispatchAndVisitorPattern
必知的技术知识:DoubleDispatchAndVisitorPattern
84 0
|
SQL 监控 Java
若依框架---PageHelper分页(十)
若依框架---PageHelper分页(十)
437 0
|
项目管理
PMP备考之路 - PMBOK第八章(项目质量管理)
PMP备考之路 - PMBOK第八章(项目质量管理)
290 0