typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍

文章目录

  • 前言
  • 一、typename
  • 二、非类型模板参数
  • 三、模板参数的特化
    • 1. 函数模板参数的特化
    • 2. 类模板的特化
  • 四、模板类成员函数声明和定义分离
    • 1. 显示实例化(不建议使用)
    • 2. 将生命和定义写在同一个.h文件中
  • 五、 继承
  • 总结


前言

typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍


一、typename

void Print(vector<int>& v)
{vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;
}

对上述Print函数进行模板化,如果不加typename会出现如下情况:
在这里插入图片描述

#include <iostream>
#include <vector>
#include <list>
using namespace std;template <class Container>
void Print(Container& v)
{typename Container::iterator it = v.begin(); // 此处要加typename修饰while (it != v.end()){cout << *it << " ";++it;}cout << endl;
}
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);Print(v);vector<double> v1;v1.push_back(1.1);v1.push_back(2.2);v1.push_back(3.3);v1.push_back(4.4);v1.push_back(5.5);Print(v1);list<double> lt;lt.push_back(1.14);lt.push_back(2.14);lt.push_back(3.14);lt.push_back(4.14);lt.push_back(5.14);Print(lt);return 0;
}

在这里插入图片描述

二、非类型模板参数

  • 比如一个静态栈,不仅需要接收类型参数, 还需要接收每个数组的长度
#include <iostream>
#include <vector>
#include <list>
using namespace std;// 静态栈
template <class T, size_t N>
class Stack
{
public:Stack(){}
private:T _a[N];int _top;
};
int main()
{Stack<int, 10> st1; // 10Stack<double, 100> st2; // 100return 0;
}

在这里插入图片描述

三、模板参数的特化

特化指的就是 特殊化处理

1. 函数模板参数的特化

  • 函数模板个格式,虽然需要加template<>,但是大多数情况下,我们可以直接去掉,与原来的函数构成函数重载,达到特化的效果
#include <iostream>
using namespace std;
// 函数模板的特化
template <class T>
bool Less(T left, T right)
{return left < right;
}// 函数模板的特化格式
template<>
bool Less<int*>(int* left, int* right)
{return *left < *right;
}int main()
{cout << Less(1, 2) << endl;int a = 2, b = 1;cout << Less(&a, &b) << endl;return 0;
}

在这里插入图片描述

2. 类模板的特化

类模板的特化包括 全特化,偏特化(半特化), 限制类型为指针, 限制类型为引用

#include <iostream>
using namespace std;// 类模板特化template <class T1, class T2>
class A
{
public:A() { cout << "A<T1, T2>" << endl; }
private:
};// 全特化
template<>
class A<int, double>
{
public:A() { cout << "A<int, double>" << endl; }
private:
};// 偏特化
template <class T1>
class A<T1, double>
{
public:A() { cout << "A<T1, double>" << endl; }
private:
};// 对类型进行限制---指针
template <class T1, class T2>
class A<T1*, T2*>
{
public:A() { cout << "A<T1*, T2*>" << endl; }
private:
};// 对类型限制---引用
template <class T1, class T2>
class A<T1&, T2&>
{
public:A() { cout << "A<T1&, T2&>" << endl; }
private:
};int main()
{A<int, int> a1;A<int, double> a2;A<double, double> a3;A<char, double> a4;A<int*, double> a5;A<int*, double*> a6;A<void*, void*> a7;A<int&, double&> a8;return 0;
}

在这里插入图片描述

四、模板类成员函数声明和定义分离

模板类成员函数声明和定义分离 有两种方式:
一种是: 在函数的定义处显示实例化
另一种是: 将生命和定义写在同一个.h文件中,(有些还将这种文件以.hpp作为后缀)

模板类成员函数声明和定义直接分离,因为模板类型T没有进行实例化,编译器在链接阶段无法找到正确的地址,所以会出现编译报错。

1. 显示实例化(不建议使用)

// Stack.h
#pragma once
#include <vector>namespace hhb
{template<class T, class Container = std::vector<T>>class stack{public:void push(const T& x);void pop();bool empty(){return _con.empty();}const T& top(){return _con.front();}private:Container _con;};}

// Stack.cpp
#include "Stack.h"namespace hhb
{template<class T, class Container>void stack<T, Container>::push(const T& x){_con.push_back(x);}template <class T, class Container>void stack<T, Container>::pop(){_con.pop_back();}templateclass stack<int>;templateclass stack<double>;
}

// test.cpp
#include "Stack.h"int main()
{hhb::stack<int> st;st.push(1);st.pop();hhb::stack<double> st1;st1.push(1.1);st1.pop();return 0;
}
  • 不会有编译错误

2. 将生命和定义写在同一个.h文件中

// Stack.h
#pragma once
#include <vector>namespace hhb
{template<class T, class Container = std::vector<T>>class stack{public:void push(const T& x);void pop();bool empty(){return _con.empty();}const T& top(){return _con.front();}private:Container _con;};template<class T, class Container>void stack<T, Container>::push(const T& x){_con.push_back(x);}template <class T, class Container>void stack<T, Container>::pop(){_con.pop_back();}}

// test.cpp
#include "Stack.h"int main()
{hhb::stack<int> st;st.push(1);st.pop();hhb::stack<double> st1;st1.push(1.1);st1.pop();return 0;
}
  • 不会有编译错误

五、 继承

访问限定符的权限 : public > protected > privated;
继承是有基类以继承方式继承给派生类
继承方式: 有三种 以 public 、 protected、 private 三种方式进行继承。
派生类对基类成员变量/成员函数的访问方式取决于: 基类的成员变量和成员函数的访问限定符以及派生类的继承方式:

  1. 基类的成员若为private, 则在派生类中无法看见(访问)基类private的成员
  2. 基类的protected和public成员, 与派生类的继承方式权限进行比较,权限小的即为在派生类中访问基类成员的访问方式。
#include <iostream>
using namespace std;
class Person
{
public:Person(){}void print(){cout << "_name: " << _name <<  endl;cout << "_age: " << _age << endl;}
protected:string _name = "perter";int _age = 10;
};class student : public Person
{
public:
private:int _sid;
};class teacher : public Person
{
public:
private:int _tid;
};int main()
{student s;s.print();teacher t;t.print();return 0;
}

在这里插入图片描述

总结

typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1545120.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于DAMODEL——Faster-RCNN 训练与测试指南

Faster-RCNN 训练与测试指南 前言 今天我们要来实现一个经典的目标检测模型&#xff1a;Faster-Rcnn。我们使用DAMODEL云平台来实现&#xff0c;这是个很强大的云端平台&#xff0c;功能众多&#xff0c;你可以投你所好去进行你想做的事情。 1. 环境与工具准备 1.1 远程连接…

【漏洞复现】用友 U8CRM getemaildata.php 任意文件读取漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

【VMware及CentOS7】安装 配置

一、VMware安装 这里选择的版本是16.1.2&#xff0c;这里不再赘述安装过程&#xff0c;无难点。 crack key&#xff1a; ZF3R0-FHED2-M80TY-8QYGC-NPKYF YF390-0HF8P-M81RQ-2DXQE-M2UT6 ZF71R-DMX85-08DQY-8YMNC-PPHV8 110L3-9135J-M807A-08ARK-84V7L FF31K-AHZD1-H8ETZ-8WWE…

性能监控之Python实战SkyWalking链路追踪

文章目录 一、介绍二、SkyWalking支持的语言三、SkyWalking安装3.1 前提准备3.2 先安装ElasticSearch7.X3.3 Skywalking-OAP 安装3.4 Skywalking-UI 界面安装3.5 访问页面检查SkyWalking是否可以访问 四、Python 项目接入SkyWalking4.1 演示项目代码4.2 验证 sw-python4.3 配置…

【最基础最直观的排序 —— 选择排序算法】

最基础最直观的排序 —— 选择排序算法 选择排序算法是一种简单直观的排序算法。其基本思想是每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;然后&#xff0c;再从剩余未排序元素中继续寻找最小&a…

模型Alignment之RLHF与DPO

1. RLHF (Reinforcement Learning from Human Feedback) RLHF 是一种通过人类反馈来强化学习的训练方法&#xff0c;它能够让语言模型更好地理解和执行人类指令。 RLHF 的三个阶段 RLHF 的训练过程一般分为三个阶段&#xff1a; 监督微调&#xff08;Supervised Fine-Tuning,…

echarts 导出pdf空白原因

问题阐述 页面样式&#xff1a; 导出pdf: 导出pdf&#xff0c;统计图部分为空白。 问题原因 由于代码中进行了dom字符串的复制&#xff0c;而echarts用canvas绘制&#xff0c;canvas内部内容不会进行复制&#xff0c;只会复制canvas节点&#xff0c;因此导出pdf空白。 解决…

1. IP地址介绍

IP地址 一、网络概述1、网络类型2、网络组成、传输介质2.1 组成2.2 传输介质 二、IP地址1、IP地址的表示方法2、IP地址的组成3、IP地址的类型3.1 根据IP地址第一个字节大小来分3.1.1 单播地址 Unicast 3.2 根据IP地址的使用 三、子网掩码 netmask1、默认的子网掩码2、判断多个I…

游戏开发2025年最新版——八股文面试题(unity,虚幻,cocos都适用)

1.静态合批与动态合批的原理是什么&#xff1f;有什么限制条件&#xff1f;为什么&#xff1f;对CPU和GPU产生的影响分别是什么&#xff1f; 原理&#xff1a;Unity运行时可以将一些物体进行合并&#xff0c;从而用一个描绘调用来渲染他们&#xff0c;就是一个drawcall批次。 限…

MyBatis—Plus 快速上手【后端 22】

MyBatis-Plus 使用入门指南 前言 在Java的持久层框架中&#xff0c;MyBatis因其灵活性和易用性而广受欢迎。然而&#xff0c;随着项目规模的扩大&#xff0c;MyBatis的一些重复性工作&#xff08;如CRUD操作&#xff09;开始显得繁琐。为了解决这一问题&#xff0c;MyBatis-Pl…

图论系列(dfs)9/24

岛屿问题&#xff1a; 二叉树dfs遍历的框架代码: 要有一个终止条件、访问相邻节点; public void dfs(Treenode root){if(rootnull)return;dfs(root.left);dfs(root.right);} 网格dfs遍历的框架代码: public void dfs(int[][] grid,int x,int y){//如果x、y坐标不在网格里面 …

专业学习|随机规划概观(内涵、分类以及例题分析)

一、随机规划概览 &#xff08;一&#xff09;随机规划的定义 随机规划是通过考虑随机变量的不确定性来制定优化决策的一种方法。其基本思想是在决策过程中&#xff0c;目标函数和约束条件可以包含随机因素。 &#xff08;1&#xff09;重点 随机规划的中心问题是选择参数&am…

学习一下怎么用git

目录 初始化操作 设置名字&#xff1a; 设置邮箱: 查询状态 初始化本地仓库 清空git bush控制台 git的三个区域 文件提交 将会文件提交到暂存区 暂存指定文件 暂存所有改动文件 查看暂存区里面的文件 将文件提交到版本库 git文件状态查看 ​编辑 暂存区的相关指令…

时序预测:LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较

引言 近年来&#xff0c;民航旅客周转量一直是衡量国家或地区民航运输总量的重要指标之一。为了揭示民航旅客周转量背后的规律和趋势&#xff0c;本研究旨在综合分析1990年至2023年的相关数据。 通过单位根检验和序列分解&#xff0c;我们确定了民航旅客周转量数据的非平稳性&…

MySQL(面试题 - 同类型归纳面试题)

目录 一、MySQL 数据类型 1. 数据库存储日期格式时&#xff0c;如何考虑时区转换问题&#xff1f; 2. Blob和text有什么区别&#xff1f; 3. mysql里记录货币用什么字段类型比较好&#xff1f; 4. MySQL如何获取当前日期&#xff1f; 5. 你们数据库是否支持emoji表情存储&…

也遇到过 PIL Image “image file is truncated“的问题

背景前言 属于活久见系列&#xff0c;最近工作上遇了该问题&#xff01; 背景&#xff1a;前端 APP使用 Android CameraX 的接口&#xff0c;拍摄并上传图片&#xff0c;然后 Python后端服务对图片裁剪与压缩处理。后端服务处理图片时有遇到image file is truncated的情况。还…

Leetcode 螺旋矩阵

算法思想&#xff1a; 这个算法的目标是按照顺时针螺旋的顺序从矩阵中取出元素。为了做到这一点&#xff0c;整个思路可以分成几个关键步骤&#xff1a; 定义边界&#xff1a;首先需要定义四个边界变量&#xff1a; left&#xff1a;当前左边界的索引。right&#xff1a;当前右…

R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

随机森林作为一种集成学习方法&#xff0c;在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性&#xff0c;随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中&#xff0c;使用Bootstrap抽样生成不同的训练集&#xff…

夜间车辆 信号灯识别检测数据集 共3500张 YOLO数据集

夜间车辆 信号灯识别检测数据集 共3500张 YOLO数据集 夜间车辆与交通信号识别检测数据集&#xff08;Nighttime Vehicle & Traffic Signal Recognition Dataset&#xff09; 数据集概述 这是一个专为夜间环境设计的车辆和交通信号识别检测数据集&#xff0c;共包含3500张…

将python代码文件转成Cython 编译问题集

准备setup.py from distutils.core import setup from Cython.Build import cythonize import glob# 指定目标目录 python setup.py build -c mingw32 target_dir "src"# 使用glob模块匹配目录中的所有.pyx文件 pyx_files glob.glob(target_dir "/**/*.py&q…