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

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模板编程技术及其发展历程 一、早期阶段&#xff08;C98及之前&#xff09; 在C98标准中&#xff0c;模板是首次被引入的关键特性之一。模板允许开发人员编写参数化的类型或函数&#xff0c;从而创建通用的算法和数据结构。这种通用性不仅提高了代码的复用性&#xff0c;还确…...

Unity 一个比较适合学习的FSM状态机(汉化和功能简述)

该轮子由网络资源而来&#xff0c;遵从作者开源意愿&#xff0c;仅作免费学习和分享&#xff0c;不作任何商业行为 &#xff0c;本文不支持任何交易行为&#xff0c;侵权删&#xff01;&#xff01;&#xff01; 至于我为什么不将此文章设置为转载&#xff0c;是因为该代码所在…...

25、Wpf之App资源应用

开发平台&#xff1a;Win10 64位 开发环境&#xff1a;VS2022(64位) Preview .NET Framework&#xff1a;.NET 6 文章目录 一 Resources1.1 Application中定义资源1.2 样式&#xff08;Styles&#xff09;1.3 模板&#xff08;Templates&#xff09;1.4 数据转换器&#xff08;…...

【深度好文】反模式:10种滥用设计模式案例分析

Hello&#xff0c;大家好&#xff0c;我是V哥。很多文章都在介绍设计模式怎么用&#xff0c;讲解设计模式的原理等等&#xff0c;设计模式的思想是编程中的精髓&#xff0c;用好了可以让代码结构利于维护和扩展&#xff0c;同时代码风格也更加优雅&#xff0c;V 哥也写过这样一…...

OkHttp Interceptor日志上报

最近为了做一些网络上的优化&#xff0c;所以就得提前埋点&#xff0c;为后续网络优化提供数据支持。 主要是对发起请求埋点&#xff0c;请求错误埋点&#xff0c;客户端请求耗时埋点。 事件上报到阿里云&#xff0c;接入的是阿里的应用实时监控服务。 网络请求使用的是OhHttp…...

高性能反向代理--HAProxy

文章目录 Web架构负载均衡介绍为什么使用负载均衡负载均衡类型 HAProxy简介应用场景HAProxy是什么HAProxy功能 脚本安装HAProxy基础配置global多进程和线程HAProxy日志配置项 Proxies配置-listen-frontend-backendserver配置 frontendbackend配置实例子配置文件 HAProxy调度算法…...

数据结构应用实例(四)——最小生成树

Content&#xff1a; 一、问题描述二、算法思想三、代码实现四、两种算法的比较五、小结 一、问题描述 利用 prim 算法和 kruskal 算法实现最小生成树问题&#xff1b; 二、算法思想 首先判断图是否连通&#xff0c;只有在连通的情况下才进行最小树的生成&#xff1b; 三、代…...

为OneAPI配置MySQL数据库及设置开机启动

OneAPI启动时&#xff0c;如果发现没有数据库他会在项目根目录自动创建SqlLit&#xff0c;为提高OneAPI的性能及管理&#xff0c;这里给出一个使用MySQL数据库的案例&#xff0c;同时本文介绍如何在源码部署的情况下&#xff0c;设置OneAPI的开机自动启动。 OneAPI的源代码安装…...

完整的k8s搭建服务器流程

一、准备 1、禁用selinux #临时禁用 setenforce 0 #永久禁用 sed -i s/enforcing/disabled/ /etc/selinux/config #检查selinux是否已禁用 sestatus 2、禁用交换分区 #命令行临时禁用 swapoff -a #永久禁用 vim /etc/fstab 注释掉有swap字样的那行&#xff0c;重启 3、允许…...

【Petri网导论学习笔记】Petri网导论入门学习(一)

Petri 网导论 如需学习转载请注明原作者并附本帖链接&#xff01;&#xff01;&#xff01; 如需学习转载请注明原作者并附本帖链接&#xff01;&#xff01;&#xff01; 如需学习转载请注明原作者并附本帖链接&#xff01;&#xff01;&#xff01; 发现网上关于Petri网的学习…...

Zabbix监控自动化

监控在运维工作中所占的比例为 30%左右&#xff0c;监控做得好&#xff0c;会省很多事&#xff0c;让工作能有序地进行。理想的监控应该是自动化的&#xff0c;只需要配置规则&#xff0c;即可自动完成所有的事情&#xff0c;比如主机的自动添加和注册、模板的自动添加、分组的…...

pytorch pyro 贝叶斯神经网络 bnn beyesean neure network svi ​定制SVI目标和培训循环,变更推理

定制SVI目标和培训循环 Pyro支持各种基于优化的贝叶斯推理方法&#xff0c;包括Trace_ELBO作为SVI(随机变分推理)的基本实现。参见文件&#xff08;documents的简写&#xff09;有关各种SVI实现和SVI教程的更多信息I, 二&#xff0c;以及罗马数字3了解SVI的背景。 在本教程中…...

Openeuler22 部署 RackTables0.22.0

目录 0、前言 一、部署lamp环境&#xff0c;lamp环境测试 1、部署Apache&#xff0c;apache环境测试 2、部署php、mysql&#xff0c;php环境测试 二、放文件 三、配置mysql 四、安装racktables 第一步、点击proceed继续 第二步、点击proceed 第三步、根据提示进行操作…...

从传统到智能:高标准农田灌区信息化助力农业现代化

从传统农业的粗放式管理&#xff0c;到如今智能化、精准化的现代农业转型&#xff0c;高标准农田灌区信息化建设无疑是推动这一历史进程的关键力量。它不仅标志着农业生产方式的根本性变革&#xff0c;还深刻影响着农业资源的高效利用与可持续发展策略&#xff0c;为实现农业现…...

堆排序-建堆,增删替换

我们 之前写过根据 堆排序的优先级队列&#xff0c;但是如果我们想要建立一个堆怎么办呢&#xff1f; 如何实现上浮 下潜 具体看这篇文章 堆排序-优先级队列-CSDN博客 建堆 我们有两种方法建立一个堆 1.我们基于add方法建立一个堆&#xff0c;一次次的add&#xff0c;然后对…...

使用AI写WebSocket知识是一种怎么样的体验?

一、WebSocket基础知识 1. WebSocket概念 1.1 为什么会出现WebSocket 一般的Http请求我们只有主动去请求接口&#xff0c;才能获取到服务器的数据。例如前后端分离的开发场景&#xff0c;自嘲为切图仔的前端大佬找你要一个配置信息的接口&#xff0c;我们后端开发三下两下开…...

若依系统(Security)增加微信小程序登录(自定义登录)

若依系统(分离版后端)自带的账号验证是基于 UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(username, password); 验证&#xff0c;然后在系统中controller或service类中 SecurityUtils 工具类中直接可获取用户或用户…...

道可云人工智能元宇宙每日资讯|2024互联网岳麓峰会在长沙召开

道可云元宇宙每日简报&#xff08;2024年9月10日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 2024互联网岳麓峰会在长沙召开 9月9日&#xff0c;2024互联网岳麓峰会在长沙召开&#xff0c;湖南省副省长曹志强在峰会表示&#xff0c;今年上半年湖南省人工智能产…...

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 模块&#xff0c;允许你发送控制命令给正在运行的 worker。其中 shutdown 命令可以用来关闭一个或多个 worker。下面是如何使用 control.shutdown 来关闭 worker 的详细说明。 使用 control.shutdown 1. 导入必要的模块 首先&#xff0c;你需要导入 C…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...