当前位置: 首页 > news >正文

C++模板基础(四)

函数模板(四)
● 函数模板的实例化控制
– 显式实例化定义: template void fun(int) / template void fun(int)

//header.h
template<typename T>
void fun(T x)
{std::cout << x << std::endl;
}
//main.cpp
#include"header.h"
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x =3;fun<int>(x); //此处用int实例化函数模板,然后调用return a.exec();
}

在这里插入图片描述

//header.h
template<typename T>
void fun(T x)
{std::cout << x << std::endl;
}
template
void fun<int>(int x); //OK,显式实例化的定义,不需要写出函数模板的实现,编译的时候编译器自动生成实现template
void fun(int x); //OK,也是一个显式实例化的定义
//main.cpp
#include"header.h"
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x =3;fun<int>(x); //头文件中已经有了一个显式实例化的版本,此处的调用刚好模板实参是int,所以此处直接调用函数模板的实例化版本return a.exec();
}

在这里插入图片描述

– 显式实例化声明: extern template void fun(int) / extern template void fun(int)

//header.h
//头文件中定义模板原型
template<typename T>
void fun(T x)
{std::cout << x << std::endl;
}
//source.cpp
//source.cpp中定义一个实例化
#include "header.h"
template
void fun<int>(int x);
//main.cpp
#include"header.h"//main.cpp中对函数模板的一个实例化的声明,在main.cpp这个翻译单元中不会再产生一个int型的实例: 减轻了编译器的负担也减轻了链接器的负担,一定程度上提升了编译和廉洁的速度
extern template //Since C++11, 模板实例化的一个声明
void fun<int>(int x);int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x =3;fun<int>(x);return a.exec();
}

在这里插入图片描述

– 注意一处定义原则

//header.h
//头文件中定义模板原型
template<typename T>
void fun(T x)
{std::cout << x << std::endl;
}
//source.cpp
#include "header.h"
//source.cpp中定义一个实例化,满足模板翻译单元级别的一处定义原则
template
void fun<int>(int x);void g()
{fun<int>(100);
}
//main.cpp
#include"header.h"
//main.cpp中定义一个实例化,满足模板翻译单元级别的一处定义原则
template
void fun<int>(int x);int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x =3;fun<int>(x);return a.exec();
}

以上代码在有的编译器上会编译并运行,但是在Qt5.14.2上报错:找到一个或多个重定义的符号
解释:An implementation is not required to diagnose a violation of this rule. 参考https://stackoverflow.com/questions/52664184/why-does-explicit-template-instantiation-not-break-odr

– 注意实例化过程中的模板形参推导

template<typename T>
void fun(T x)
{std::cout << x << std::endl;
}template<typename T>
void fun(T* x)
{std::cout << x << std::endl;
}template
void fun<int*>(int* x); //此处是template<typename T>void fun(T x)的实例化定义int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);return a.exec();
}
#include<iostream>
template<typename T>
void fun(T x)
{std::cout << "template<typename T> void fun(T x)" << x << std::endl;
}template<typename T>
void fun(T* x)
{std::cout << "template<typename T> void fun(T* x)" << x << std::endl;
}template //注意模板实例化的位置,在两个模板之后
void fun(int* x); //此处是template<typename T>void fun(T* x)的一个实例化int mian()
{
}
//https://cppinsights.io/里的编译输出结果
#include<iostream>
template<typename T>
void fun(T x)
{(std::operator<<(std::cout, "template<typename T> void fun(T x)") << x) << std::endl;
}template<typename T>
void fun(T * x)
{(std::operator<<(std::cout, "template<typename T> void fun(T* x)") << x) << std::endl;
}/* First instantiated from: insights.cpp:15 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void fun<int>(int * x)
{std::operator<<(std::cout, "template<typename T> void fun(T* x)").operator<<(reinterpret_cast<const void *>(x)).operator<<(std::endl);
}
#endiftemplate
void fun(int* x);int mian()
{
}
#include<iostream>
template<typename T>
void fun(T x)
{std::cout << "template<typename T> void fun(T x)" << x << std::endl;
}template //注意模板实例化的位置,在第一个模板之后,是template<typename T>void fun(T x)的实例化
void fun(int* x);template<typename T>
void fun(T* x)
{std::cout << "template<typename T> void fun(T* x)" << x << std::endl;
}int mian()
{
}
#include<iostream>
template<typename T>
void fun(T x)
{(std::operator<<(std::cout, "template<typename T> void fun(T x)") << x) << std::endl;
}/* First instantiated from: insights.cpp:9 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void fun<int *>(int * x)
{std::operator<<(std::cout, "template<typename T> void fun(T x)").operator<<(reinterpret_cast<const void *>(x)).operator<<(std::endl);
}
#endiftemplate
void fun(int* x);template<typename T>
void fun(T * x)
{(std::operator<<(std::cout, "template<typename T> void fun(T* x)") << x) << std::endl;
}int mian()
{
}

● 函数模板的 ( 完全 ) 特化: template<> void f(int) / template<> void f(int)
– 并不引入新的(同名)名称,只是为某个模板针对特定模板实参提供优化算法
– 注意与重载的区别
– 注意特化过程中的模板形参推导

参考
深蓝学院:C++基础与深度解析
C++ Insights

相关文章:

C++模板基础(四)

函数模板&#xff08;四&#xff09; ● 函数模板的实例化控制 – 显式实例化定义&#xff1a; template void fun(int) / template void fun(int) //header.h template<typename T> void fun(T x) {std::cout << x << std::endl; }//main.cpp #include&quo…...

pycharm使用记录

文章目录下载安装后续其他设置编辑器设置关于debug下载安装 直接去pycharm官网下载社区版&#xff0c;这个版本本来就是免费的&#xff0c;而且功能其实已经够了 后续其他设置 首先&#xff0c;第一次启动时&#xff0c;记得在preference->interpreter中设置python环境&a…...

Linux命令·kill·killall

Linux中的kill命令用来终止指定的进程&#xff08;terminate a process&#xff09;的运行&#xff0c;是Linux下进程管理的常用命令。通常&#xff0c;终止一个前台进程可以使用CtrlC键&#xff0c;但是&#xff0c;对于一个后台进程就须用kill命令来终止&#xff0c;我们就需…...

Linux /proc/version 文件解析

/proc/version文件里面的内容: Linux version 4.14.180-perf (oe-user@oe-host) (clang version 10.0.5 for Android NDK, GNU ld (GNU Binutils) 2.29.1.20180115) #1 SMP PREEMPT Wed Mar 29 18:55:02 CST 2023 /proc/version文件里面记录了如下内容: 1、Linux kernel的…...

【Django 网页Web开发】15. 实战项目:管理员增删改查,md5密码和密码重置(08)(保姆级图文)

目录1. model编写数据表2. 管理员列表2.1 admin.py视图文件2.2 admin_list.html2.3 url.py2.4 最终效果3. 管理员添加3.0 md5包的书写3.1 form.py表单组件3.2 admin.py视图文件3.3 引入公共的添加数据html3.4 url.py3.5 最终效果4. 管理员编辑4.0 form表单组件4.1 admin.py视图…...

STL容器之<array>

文章目录测试环境array介绍头文件模块类定义对象构造初始化元素访问容器大小迭代器其他函数测试环境 系统&#xff1a;ubuntu 22.04.2 LTS 64位 gcc版本&#xff1a;11.3.0 编辑器&#xff1a;vsCode 1.76.2 array介绍 array是固定大小的序列式容器&#xff0c;它包含按严格…...

flask教程6:cookie和session

文章目录一、cookie1.1 什么是cookie&#xff1f;1.2 使用cookie1.2.1 设置cookie1.2.2设置cookie的有效期1.2.3在Flask中查询cookie1.2.4删除cookie二、session2.1实现session的两种思路2.1.1 第一种2.1.2 第二种2.2使用session2.2 .1设置session2.2.2 设置有效期2.2.3 获取se…...

【JavaEE初阶】第六节.网络原理TCP/IP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、TCP/IP协议五层协议栈&#xff1b; 1.1 应用层协议&#xff1b; 二、传输层协议&#xff1b; 2.1 UDP协议&#xff1b; 2.2 TCP协议&#xff1b; 2.…...

模式识别 —— 第六章 支持向量机(SVM)与核(Kernel)

模式识别 —— 第六章 支持向量机&#xff08;SVM&#xff09;与核&#xff08;Kernel&#xff09; 文章目录模式识别 —— 第六章 支持向量机&#xff08;SVM&#xff09;与核&#xff08;Kernel&#xff09;硬间隔&#xff08;Hard-Margin&#xff09;软间隔&#xff08;Soft…...

总结 synchronized

目录synchronized的特性1. 互斥2. 刷新内存3. 可重入synchronized的使用1. 直接修饰普通方法2. 修饰静态方法3. 修饰代码块synchronized的锁机制基本特点关键锁策略 : 锁升级synchronized的特性 1. 互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized…...

360周鸿祎又“开炮”:GPT 6-8就将产生自主意识!我们来测算一下对错

‍数据智能产业创新服务媒体——聚焦数智 改变商业近日&#xff0c;360的周鸿祎放言“GPT6到GPT8人工智能将会产生意识&#xff0c;变成新的物种。未来&#xff0c;人工智能大语言模型有可能实现自我进化&#xff0c;自动更新系统和自我升级&#xff0c;或者指数级进化能力&am…...

python——飞机大战小游戏

目录 1、导入模块 2、窗口操作 3、事件操作 4、长按事件 5、添加游戏背景 6、添加英雄飞机 7、获取飞机的图片矩形 8、基本游戏窗口 9、添加游戏窗口图片 10、英雄飞机登场 11、英雄飞机装备子弹并发射 1、enemy_plane 2、game_main 3、game_map 4、game_score …...

数组(完全二叉树)向下建堆法与堆排序O(N*logN)

TIPS AdjustUp & AdjustDown向上调整AdjustUp与向下调整AdjustDown的参数是一个数组&#xff08;完全二叉树&#xff09;需要进行调整操作的数值的下标/一个数组&#xff08;完全二叉树&#xff09;堆元素个数需要调整操作的数值的下标。实际上就是对完全二叉树当中的某一点…...

Lua require 函数使用

从 Lua 的用户文档中我们知道 require("modName") 函数是用来加载模块的&#xff0c;而如果这个modName已经用require 加载过的&#xff0c;再调用require时&#xff0c;将直接返回模块的值。因为函数首先查找 package.loaded 表&#xff0c; 检测 modName 是否被加载…...

【面试】如何定位线上问题?

这个面试题我在两年社招的时候遇到过&#xff0c;前几天面试也遇到了。我觉得我每一次都答得中规中矩&#xff0c;今天来梳理复盘下&#xff0c;下次又被问到的时候希望可以答得更好。 下一次我应该会按照这个思路去答&#xff1a; 1、如果线上出现了问题&#xff0c;我们更多…...

字节二面,原来我对自动化测试的理解太浅了

如果你入职一家新的公司&#xff0c;领导让你开展自动化测试&#xff0c;作为一个新人&#xff0c;你肯定会手忙脚乱&#xff0c;你会如何落地自动化测试呢&#xff1f; 01 什么是自动化 有很多人做了很长时间的自动化但却连自动化的概念都不清楚&#xff0c;这样的人也是很悲…...

Android11.0 应用升级成功后立即断电重启,版本恢复

问题&#xff1a;客户反馈内置的应用升级成功后立刻断电重启&#xff0c;应用的版本被恢复。 使用adb命令升级客户应用&#xff0c;查看版本显示已更新&#xff0c;/data/system目录下packages.xml和packages.xml中应用版本信息均已更新 C:\Users\dell>adb shell dumpsys …...

关于python常用软件用法:Pycharm 常用功能

人生苦短&#xff0c;我用python 一.Pycharm的基本使用 1.在Pycharm下为你的Python项目配置Python解释器 &#xff08;1&#xff09;.Setting>Project Interpreter>源码资料电子书:点击此处跳转文末名片获取 二.在Pycharm下创建Python文件、Python模块 1.File>New&g…...

SOLIDWORKS你不知道的小技巧

◉ SOLIDWORKS圆弧长度标注点智能标注&#xff0c;再选中该圆弧&#xff0c;然后分别点圆弧的两个端点&#xff0c;点击左键可以标注圆弧长度。◉ SOLIDWORKS强力裁剪剪裁实体中的强劲剪裁&#xff0c;除了可以裁剪实体外&#xff0c;还可以任意延伸实体。◉ SOLIDWORKS转折线转…...

有了HTTP,为啥还要用RPC

既然有 HTTP 请求&#xff0c;为什么还要用 RPC 调用&#xff1f; 一直以来都没有深究过RPC和HTTP的区别&#xff0c;不都是写一个服务然后在客户端调用么&#xff1f; HTTP和RPC最本质的区别&#xff0c;就是 RPC 主要是基于 TCP/IP 协议的&#xff0c;而 HTTP 服务主要是基…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...