c++的模板编程技术及其发展历程
C++模板编程技术及其发展历程
一、早期阶段(C++98及之前)
在C++98标准中,模板是首次被引入的关键特性之一。模板允许开发人员编写参数化的类型或函数,从而创建通用的算法和数据结构。这种通用性不仅提高了代码的复用性,还确保了类型安全性,因为模板实例化是在编译时由编译器自动完成的。
-
技术要点:
- 函数模板:允许为任意类型创建函数的实例。
- 类模板:允许为任意类型创建类的实例。
- 参数包:允许函数或类模板接受可变数量的参数。
-
使用方法:
// 函数模板示例 template<typename T> void swap(T& a, T& b) { // 定义一个交换两个同类型变量的函数模板T temp = a; // 复制a的值到临时变量tempa = b; // 将b的值赋给ab = temp; // 将temp的值(原来的a的值)赋给b }// 类模板示例 template<typename T> class Stack { private:std::vector<T> elements; // 使用vector存储元素public:void push(const T& element) { // 向栈中压入一个元素elements.push_back(element);}T pop() { // 从栈顶弹出一个元素T topElement = elements.back();elements.pop_back();return topElement;}bool empty() const { // 判断栈是否为空return elements.empty();} };// 参数包示例 template<typename... Args> void printValues(Args... args) { // 接受可变数量的参数(std::cout << ... << args) << '\n'; // 使用折叠表达式打印所有参数 }int main() {int a = 1, b = 2; // 定义两个整数变量double c = 3.5, d = 4.5; // 定义两个浮点数变量swap(a, b); // 调用int类型的swap函数swap(c, d); // 调用double类型的swap函数// 输出结果验证交换是否成功std::cout << "After swapping: a=" << a << ", b=" << b << std::endl;std::cout << "After swapping: c=" << c << ", d=" << d << std::endl;// 使用类模板创建一个整数栈Stack<int> intStack;intStack.push(1);intStack.push(2);intStack.push(3);while (!intStack.empty()) {std::cout << "Popped: " << intStack.pop() << std::endl;}// 使用参数包打印多个值printValues(1, 2, 3.5, "Hello", 'A'); // 打印不同类型的值return 0; } -
改进的意义:
通过模板,开发者可以编写一次代码,然后通过不同的类型参数实例化多次,减少了代码重复并提高了程序的可维护性。类模板允许创建通用的数据结构,而参数包使得函数可以处理不确定数量的参数,增强了函数的灵活性和实用性。
接下来是关于C++03至C++11阶段的内容,如果您需要进一步的修改或补充,请告诉我。
二、扩展与增强阶段(C++03至C++11)
C++03标准主要是一个修正版本,没有引入太多新特性,但C++11带来了许多重要的改进,特别是在模板编程领域。
-
技术要点:
- 模板特化:允许为特定类型提供特殊的模板实现。
- 偏特化:允许为部分模板参数提供特定实现。
auto关键字:自动类型推导,简化了模板中的类型声明。- Lambda表达式:允许在模板内定义简洁的一次性使用的函数对象。
-
使用方法:
// 模板特化示例 template<typename T> struct identity {static T value; };template<typename T> T identity<T>::value = T();// 为int类型特化identity template<> struct identity<int> {static const int value = 42; };// Lambda表达式示例 std::vector<int> vec = {1, 2, 3, 4, 5}; std::for_each(vec.begin(), vec.end(), [](int& x) { x *= 2; }); // 使用Lambda表达式修改vector元素int main() {// 输出identity<int>::value的值std::cout << "Identity of int: " << identity<int>::value << std::endl;for (const auto& v : vec) {std::cout << v << " ";}std::cout << std::endl;return 0; } -
改进的意义:
特化和偏特化让模板更加强大,能够处理更多复杂的类型和边缘情况。auto关键字和Lambda表达式的加入,提高了代码的可读性和编写效率。
三、进一步优化与扩展阶段(C++14至C++20)
随着C++14和后续版本的推出,模板编程变得更加高效和强大。
-
技术要点:
- 变量模板:允许创建参数化的变量,类似于函数模板。
- 折叠表达式:允许在模板中对参数包进行递归或迭代操作。
- 模块化编程:虽然在C++20中正式引入,但其概念影响了模板的设计,使得代码组织更加清晰。
-
使用方法:
// 变量模板示例 template<typename T> constexpr T pi = T(3.14159265358979323846); // 定义一个pi变量模板// 折叠表达式示例 template<typename... Args> auto sum(Args&&... args) {return (args + ...); // 折叠表达式,将所有参数加起来 }int main() {// 创建float类型的piauto piFloat = pi<float>;std::cout << "Pi as float: " << piFloat << std::endl;// 计算不同类型的数之和,自动类型推导为doubleauto sumResult = sum(1, 2, 3.5, 4LL);std::cout << "Sum result: " << sumResult << std::endl;return 0; } -
改进的意义:
变量模板允许在编译期创建常量,增强了编译时计算的能力。折叠表达式简化了参数包的操作,使得编写元编程代码更为直观。模块化编程改进了大型项目的构建和维护,减少了编译时间和错误。
四、最新进展(C++23)
C++23标准继续推进了模板编程技术的发展,引入了一些新的特性,进一步增强了模板的功能性和灵活性。
-
技术要点:
- 概念约束的模板参数:C++20引入了概念(concepts),而在C++23中,概念被进一步应用于模板参数的约束。
- 模板参数推导:C++23允许在模板函数或类模板中推导出模板参数。
- 模板参数默认值:C++23允许为模板参数提供默认值,这使得模板更加灵活。
- 模板模板参数的默认值:允许为模板模板参数指定默认模板。
-
使用方法:
// 概念约束的模板参数示例 concept Numeric = requires(T t) { t + t; };template<Numeric T> T add(T a, T b) {return a + b; }// 模板参数推导示例 template<typename T, T value> struct ConstValue {static constexpr T val = value; };// 模板参数默认值示例 template<typename T, T value = 0> struct DefaultValue {static constexpr T val = value; };// 模板模板参数的默认值示例 template<template<typename...> typename Container = std::vector, typename... Args> struct DefaultContainer {using type = Container<Args...>; };int main() {// 使用概念约束的add函数auto result = add(1, 2); // 正确调用,因为int满足Numeric概念// auto result2 = add("Hello", "World"); // 编译错误,因为std::string不能满足Numeric概念// 使用模板参数推导static_assert(ConstValue<int, 10>::val == 10);// 使用模板参数默认值static_assert(DefaultValue<int>::val == 0);static_assert(DefaultValue<int, 5>::val == 5);// 使用模板模板参数默认值using IntVector = DefaultContainer<int>::type; // 等价于std::vector<int>using DoubleVector = DefaultContainer<std::vector, double>::type; // 显式指定模板模板参数return 0; } -
改进的意义:
C++23的新特性进一步提高了模板编程的灵活性和可读性,使代码更加简洁明了。概念约束使得类型检查更加严格,而模板参数推导和默认值则简化了模板的使用,提高了代码的可维护性和易用性。
通过这些阶段的演变,我们可以看到模板编程技术如何不断地适应和发展,以满足日益复杂的软件开发需求。模板编程已经成为C++语言中不可或缺的一部分,为开发者提供了强大的工具来构建高效、可扩展的应用程序。
如果您有任何具体的要求或需要进一步的细节,请随时告知,我将尽力补充完整。
相关文章:
c++的模板编程技术及其发展历程
C模板编程技术及其发展历程 一、早期阶段(C98及之前) 在C98标准中,模板是首次被引入的关键特性之一。模板允许开发人员编写参数化的类型或函数,从而创建通用的算法和数据结构。这种通用性不仅提高了代码的复用性,还确…...
Unity 一个比较适合学习的FSM状态机(汉化和功能简述)
该轮子由网络资源而来,遵从作者开源意愿,仅作免费学习和分享,不作任何商业行为 ,本文不支持任何交易行为,侵权删!!! 至于我为什么不将此文章设置为转载,是因为该代码所在…...
25、Wpf之App资源应用
开发平台:Win10 64位 开发环境:VS2022(64位) Preview .NET Framework:.NET 6 文章目录 一 Resources1.1 Application中定义资源1.2 样式(Styles)1.3 模板(Templates)1.4 数据转换器(…...
【深度好文】反模式:10种滥用设计模式案例分析
Hello,大家好,我是V哥。很多文章都在介绍设计模式怎么用,讲解设计模式的原理等等,设计模式的思想是编程中的精髓,用好了可以让代码结构利于维护和扩展,同时代码风格也更加优雅,V 哥也写过这样一…...
OkHttp Interceptor日志上报
最近为了做一些网络上的优化,所以就得提前埋点,为后续网络优化提供数据支持。 主要是对发起请求埋点,请求错误埋点,客户端请求耗时埋点。 事件上报到阿里云,接入的是阿里的应用实时监控服务。 网络请求使用的是OhHttp…...
高性能反向代理--HAProxy
文章目录 Web架构负载均衡介绍为什么使用负载均衡负载均衡类型 HAProxy简介应用场景HAProxy是什么HAProxy功能 脚本安装HAProxy基础配置global多进程和线程HAProxy日志配置项 Proxies配置-listen-frontend-backendserver配置 frontendbackend配置实例子配置文件 HAProxy调度算法…...
数据结构应用实例(四)——最小生成树
Content: 一、问题描述二、算法思想三、代码实现四、两种算法的比较五、小结 一、问题描述 利用 prim 算法和 kruskal 算法实现最小生成树问题; 二、算法思想 首先判断图是否连通,只有在连通的情况下才进行最小树的生成; 三、代…...
为OneAPI配置MySQL数据库及设置开机启动
OneAPI启动时,如果发现没有数据库他会在项目根目录自动创建SqlLit,为提高OneAPI的性能及管理,这里给出一个使用MySQL数据库的案例,同时本文介绍如何在源码部署的情况下,设置OneAPI的开机自动启动。 OneAPI的源代码安装…...
完整的k8s搭建服务器流程
一、准备 1、禁用selinux #临时禁用 setenforce 0 #永久禁用 sed -i s/enforcing/disabled/ /etc/selinux/config #检查selinux是否已禁用 sestatus 2、禁用交换分区 #命令行临时禁用 swapoff -a #永久禁用 vim /etc/fstab 注释掉有swap字样的那行,重启 3、允许…...
【Petri网导论学习笔记】Petri网导论入门学习(一)
Petri 网导论 如需学习转载请注明原作者并附本帖链接!!! 如需学习转载请注明原作者并附本帖链接!!! 如需学习转载请注明原作者并附本帖链接!!! 发现网上关于Petri网的学习…...
Zabbix监控自动化
监控在运维工作中所占的比例为 30%左右,监控做得好,会省很多事,让工作能有序地进行。理想的监控应该是自动化的,只需要配置规则,即可自动完成所有的事情,比如主机的自动添加和注册、模板的自动添加、分组的…...
pytorch pyro 贝叶斯神经网络 bnn beyesean neure network svi 定制SVI目标和培训循环,变更推理
定制SVI目标和培训循环 Pyro支持各种基于优化的贝叶斯推理方法,包括Trace_ELBO作为SVI(随机变分推理)的基本实现。参见文件(documents的简写)有关各种SVI实现和SVI教程的更多信息I, 二,以及罗马数字3了解SVI的背景。 在本教程中…...
Openeuler22 部署 RackTables0.22.0
目录 0、前言 一、部署lamp环境,lamp环境测试 1、部署Apache,apache环境测试 2、部署php、mysql,php环境测试 二、放文件 三、配置mysql 四、安装racktables 第一步、点击proceed继续 第二步、点击proceed 第三步、根据提示进行操作…...
从传统到智能:高标准农田灌区信息化助力农业现代化
从传统农业的粗放式管理,到如今智能化、精准化的现代农业转型,高标准农田灌区信息化建设无疑是推动这一历史进程的关键力量。它不仅标志着农业生产方式的根本性变革,还深刻影响着农业资源的高效利用与可持续发展策略,为实现农业现…...
堆排序-建堆,增删替换
我们 之前写过根据 堆排序的优先级队列,但是如果我们想要建立一个堆怎么办呢? 如何实现上浮 下潜 具体看这篇文章 堆排序-优先级队列-CSDN博客 建堆 我们有两种方法建立一个堆 1.我们基于add方法建立一个堆,一次次的add,然后对…...
使用AI写WebSocket知识是一种怎么样的体验?
一、WebSocket基础知识 1. WebSocket概念 1.1 为什么会出现WebSocket 一般的Http请求我们只有主动去请求接口,才能获取到服务器的数据。例如前后端分离的开发场景,自嘲为切图仔的前端大佬找你要一个配置信息的接口,我们后端开发三下两下开…...
若依系统(Security)增加微信小程序登录(自定义登录)
若依系统(分离版后端)自带的账号验证是基于 UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(username, password); 验证,然后在系统中controller或service类中 SecurityUtils 工具类中直接可获取用户或用户…...
道可云人工智能元宇宙每日资讯|2024互联网岳麓峰会在长沙召开
道可云元宇宙每日简报(2024年9月10日)讯,今日元宇宙新鲜事有: 2024互联网岳麓峰会在长沙召开 9月9日,2024互联网岳麓峰会在长沙召开,湖南省副省长曹志强在峰会表示,今年上半年湖南省人工智能产…...
MySQL JDBC URL各参数详解
jdbc:mysql://localhost:3306/test?userroot&password123456&useUnicodetrue&characterEncodinggbk &autoReconnecttrue&failOverReadOnlyfalse&serverTimezoneUTC&drivercom.mysql.cj.jdbc.Driver 参数名称参数说明缺省值user指定用于连接数据库…...
celery control.shutdown
Celery 提供了 control 模块,允许你发送控制命令给正在运行的 worker。其中 shutdown 命令可以用来关闭一个或多个 worker。下面是如何使用 control.shutdown 来关闭 worker 的详细说明。 使用 control.shutdown 1. 导入必要的模块 首先,你需要导入 C…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器
从本章节开始,进入到函数有多个参数的情况,前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参,ECX是整型的第一个参数的寄存器,那么多个参数的情况下函数如何传参,下面展开介绍参数为整型时候的几种情…...
