C++模板函数
C++模板函数
- 函数模板
- 简单的函数模板
- 模板类型推导
- 返回输入的类型,模板返回的类型由输入的决定
- 返回类型的模板参数
- 返回值使用auto,编译器自动推导
- 默认模板实参
- 模板参数
- 重载函数模板
- constexpr关键字
函数模板
简单的函数模板
typename 可以使用class代替,但是不可以是使用struct代替。
template <typename T>
T mmax(T a, T b)
{return b < a ? a : b;
}
模板类型推导
返回输入的类型,模板返回的类型由输入的决定
template <typename T>
T mmax(T a, T b)
{return b < a ? a : b;
}
T是由输入的参数类型推导出来的,输入int T就是int型的。
如果a 和 b一个是int一个是double就需要定义两个typename。
template <typename T1, typename T2>
T1 mmax(T1 a, T2 b)
{return b < a ? a : b;
}
返回类型的模板参数
当模板参数和调用参数之间没有关联的时候,且模板参数不确定的时候,必须在调用时显式指定模板实参。
添加三个模板类型,调用的时候必须指定模板的返回类型
template <typename TR, typename T1, typename T2>
TR mmax(T1 a, T2 b)
{return b < a ? a : b;
}std::cout << mmax<int>(10.3,6)<< endl;
返回值使用auto,编译器自动推导
从C++14开始,可以通过不声明任何返回类型来实现。
template <typename T1, typename T2>
auto mmax(T1 a, T2 b) -> typename std::decay<decltype(b < a ? a : b)>::type
{return b < a ? a : b;
}
这里使用了类型特征 std::decay<>,其返回结果类型为成员type 。 std::decay<>在标准库<type_traits> 中定义。由于其成员type是一个类型,因此必须用typename修饰这个表达式才能访问它。
从C++11,C++标准库提供了一种指定选择“更一般的类型”的方法。std::common_type<>::type 萃取作为模板实参传递的两个或多个不同类型的“公共类型”。
C++11写法
template <typename T1, typename T2>
typename std::common_type<T1, T2>::type mmax(T1 a, T2 b)
{return b < a ? a : b;
}
C++ 14 写法
template <typename T1, typename T2>
std::common_type_t<T1, T2> mmax(T1 a, T2 b)
{return b < a ? a : b;
}
std::common_type<> 也是在标准库<type_traits> 中。
它可以萃取一个具有作为结果类型的type 成员的结构体。
其核心用法:
typename std::common_type<T1, T2>::type
从C++14 开始,可以通过在特征名称后面附加_t 并省略typename 和 ::type
std::common_type_t<T1, T2>
在内部它根据运算符?:的语法规则或具体的类型的特化来选择类型。
默认模板实参
使用三目运算符?: 不过必须在a和b参数调用之前使用。
template <typename T1, typename T2, typename TR = std::decay_t<decltype(true ? T1() : T2())>>
TR mmax(T1 a, T2 b)
{return b < a ? a : b;
}
使用std::common_type<> 类型特征来指定返回类型的默认值:
template <typename T1, typename T2, typename TR = std::common_type_t<T1, T2>>
TR mmax(T1 a, T2 b)
{return b < a ? a : b;
}
需要注意的是,std::common_type<> 会进行退化,因此返回类型不可能变成引用类型。
模板参数
template<typename T, int N>
void Print(T a)
{std::vector<T> num;for(int i = 0; i < N; ++i){num.push_back(i + a);}for(auto& value : num){std::cout << static_cast<T>(value) << std::endl;}
}
重载函数模板
int mmax(int a, int b)
{return b < a? a : b;
}template<typename T>
T mmax(T a, T b)
{return b < a? a : b;
}std::cout << mmax(10.3,6.1)<< endl; //使用的模板函数
一个模板函数可以和一个普通函数同名且可以用相同类型实例化的函数模板共存。在所有其他因素都相同的情况下,重载解析过程优先选择非模板函数。
std::cout << mmax('a', 6) << endl;
由于模板参数推导不允许自动类型转换,而普通函数可以,因此此函数使用的是非模板函数。
template <typename T1, typename T2>
auto mmax(T1 a, T1 b)
{return b < a ? a : b;
}template <typename TR, typename T1, typename T2>
TR mmax(T1 a, T1 b)
{return b < a ? a : b;
}
auto a = mmax<double, int>(10.3, 6);使用第一个模板
auto b = mmax<long, double>(10.3, 6); 使用第二个模板
auto c = mmax<int>(10.3, 6); 错误: 两个模板都能匹配
两个模板都能匹配通常会造成重载解析过程中无从选择,并产生歧义。因此在重载函数模板时,应该确保对于任何调用,其中只有一个与之匹配。
constexpr关键字
从C++11开始,可以使用关键字constexpr来启用在编译器使用代码计算某些数值的功能。
constexpr int Sum(int a, int b)
{return a + b;
}
int Iarray[Sum(10,3)];
使用这个关键字修饰函数就可以自定义数组大小,如果不用这个关键字修饰代码编译会出错的。
相关文章:
C++模板函数
C模板函数 函数模板简单的函数模板模板类型推导返回输入的类型,模板返回的类型由输入的决定返回类型的模板参数返回值使用auto,编译器自动推导 默认模板实参模板参数重载函数模板 constexpr关键字 函数模板 简单的函数模板 typename 可以使用class代替…...
c#中的正则表达式和日期的使用(超全)
在 C# 中,正则表达式(Regular Expressions)是一种强大的文本处理工具,用于执行各种字符串搜索、替换和验证任务。以下是一些常用的正则表达式示例及其用途: 1. 邮箱地址验证 string emailPattern "^[^\s][^…...
论文阅读【检测】:商汤 ICLR2021 | Deformable DETR
文章目录 论文地址AbstractMotivation技术细节多尺度backbone特征MSDeformAttention 小结 论文地址 Deformable DETR 推荐视频:bilibili Abstract DETR消除对目标检测中许多手工设计的组件的需求,同时表现出良好的性能。然而,由于Transfor…...
dpdk发送udp报文
dpdk接收到udp报文后,自己构造一个udp报文,将收到的报文中的源mac,目的mac,源ip,目的ip,源端口和目的端口交换下顺序填充到新的udp报文中,报文中的负载数据和收到的udp保持一致。 注࿱…...
网站后端管理和构建java项目的工具-Maven
maven是用于管理和构建java项目的工具。 管理Jar包 无论是使用eclipse、IDEA创建的maven项目,格式都是统一的。 不同开发工具创建的maven项目兼容。 test是对main测试的代码。main中的resources中放置配置文件。 对于Maven,一个Maven项目就是一个对象…...
深入理解计算机系统 CSAPP 家庭作业11.10
A: //home.html <form action"/cgi-bin/adder" method"GET"><ul><li><label for"n1">n1:</label><input type"text" id"n1" name"n1" /> //name的值决定页面提交后…...
Unity3D 二进制序列化器详解
前言 在Unity3D开发中,二进制序列化是一种重要的数据持久化和网络传输技术。通过二进制序列化,游戏对象或数据结构可以被转换成二进制格式,进而高效地存储于文件中或通过网络传输。本文将详细介绍Unity3D中的二进制序列化技术,包…...
js_拳皇(上)
文章目录 架构设计:一图胜千言绪论不能正常加载动图设计的思路渲染画布开发感想角色抽象为矩形ctx 是 canvas 的对象键盘控制角色Set键盘事件流程图在 canvas 里面使用 gif 图片继承存储动作ReferenceError: gif is not definedTypeError: Cannot read properties o…...
TCP请求如何获取客户端真实源IP地址
应用场景 在基于TCP的应用程序中,获取客户端真实源IP地址可以用于以下应用场景: 访问控制和安全策略:通过获取客户端真实源IP地址,应用程序可以实施访问控制策略,限制或允许特定IP地址的访问。这可以用于身份验证、防…...
【b站-湖科大教书匠】6 应用层 - 计算机网络微课堂
课程地址:【计算机网络微课堂(有字幕无背景音乐版)】 https://www.bilibili.com/video/BV1c4411d7jb/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 6 应用层 6.1 应用层概述 6.2 客户-服务器方式和对等方…...
QT串口和数据库通信
创建串口 串口连接客户端并向服务器发送消息 client.pro #------------------------------------------------- # # Project created by QtCreator 2024-07-02T14:11:20 # #-------------------------------------------------QT core gui network QT core gui…...
WebKitWebKit简介及工作流程
简介 引擎能够解析HTML、CSS、JavaScript等网页标准,从而将互联网内容呈现给用户。 WebKit的主要特点包括: 开源性:它是一个开源项目,任何人都可以查看、修改和贡献代码。跨平台:WebKit可以在多个操作系统上运行&am…...
架构分析(CPU:ARM vs RISC-V)
ARM N2 ARM V2 对比 N2和V2,整体架构具有一致性。保证 SiFive P870 P870 Pipeline Veyron V1...
使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录
前言 RabbitMQ 是一个功能强大的开源消息队列系统,它实现了高效的消息通信和异步处理。 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验。 特点 成熟,稳定消息持久化灵活的消息路由高性能,高可用性,可扩展性高支…...
前端八股速通(持续更新中...)
1、深拷贝和浅拷贝的区别 浅拷贝:浅拷贝是拷贝一层,引用类型共享地址。 如果属性是基本类型,拷贝的就是基本类型的值。 如果属性是引用类型,拷贝的就是内存地址。 意思是,当进行浅拷贝时,对于对象的每一…...
【语音识别和生成】语音识别和语音合成技术
语音识别和生成:语音识别和语音合成技术 目录 引言语音识别技术 语音识别的基本原理语音识别系统的组成语音识别的关键技术 语音合成技术 语音合成的基本原理语音合成系统的组成语音合成的关键技术 语音识别和生成的应用 智能助理智能家居语音翻译医疗健康教育和学…...
Redis#架构师面试题
1、Redis锁存在哪些问题及如何解决? 1、死锁问题 加过期时间设定 2、原子性问题 通过“set…nx...ex…”命令,将加锁、过期命令编排到一起,它们是原子操作了,可以避免死锁。 3、释放其他线程的锁问题 当过期时间设置小于线程…...
关于#define的使用方法总结
文章目录 #define 预处理指令一、#define宏定义二、查看预处理文件三、#define 的使用方法四、C语言宏中“#”和“##”的用法五、常见的宏定义总结六、常考题目 #define 预处理指令 #define 是 C 和 C 编程语言中的预处理指令,用于定义宏(macro…...
Unity顶点动画(Vertex Animation):创造动态视觉效果
在Unity中,顶点动画(Vertex Animation)是一种强大的技术,它允许开发者直接在顶点级别上操作和变形网格,从而实现各种动态视觉效果。顶点动画不依赖于骨骼绑定,因此非常适合模拟布料、流体、面部表情等复杂的动画效果。本文将探讨顶…...
WSL for Windows
1、安装 超详细Windows10/Windows11 子系统(WSL2)安装Ubuntu20.04(带桌面环境)_wsl安装ubuntu20.04-CSDN博客https://blog.csdn.net/weixin_44301630/article/details/122390018 注意,安装之后首次启动 Ubuntu 时&…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...
