C++新经典模板与泛型编程:将trait类模板用作模板参数

将trait类模板用作模板参数

template<typename T>
struct SumFixedTraits;template<>
struct SumFixedTraits<char>
{using sumT = int;static sumT initValue() {return 0;}
};template<>
struct SumFixedTraits<int>
{using sumT = __int64;static sumT initValue() {return 0;}
};template<>
struct SumFixedTraits<double>
{using sumT = double;static sumT initValue() {return 0.0;}
};template<typename T>
auto funcsum(const T* begin, const T* end)
{using sumT = typename SumFixedTraits<T>::sumT;sumT sum = SumFixedTraits<T>::initValue();for (;;){sum += (*begin);if (begin == end)break;++begin;}return sum;
}

funcsum()函数模板用于计算数组元素的和值。下面,给funcsum()函数模板增加一个模板参数以进一步增加funcsum()函数模板的灵活性。修改后的funcsum()函数模板代码如下。

template<typename T,typename U = SumFixedTraits<T>>
auto funcsum(const T* begin, const T* end)
{// using sumT = typename SumFixedTraits<T>::sumT;  本行不需要// sumT sum = SumFixedTraits<T>::initValue();  本行不需要typename U::sumT sum = U::initValue();for (;;){sum += (*begin);if (begin == end)break;++begin;}return sum;
}

在上面的代码中,引入了第2个类型模板参数U,该模板参数有一个默认值,而且这个默认值可以通过第1个模板参数推断出来(第2个模板参数依赖于第1个模板参数),所以一般不需要指定。但如果有特殊的需求,也是可以指定的,这就增加了funcsum()函数模板使用时的灵活性。
main()主函数中以往的代码行如下。

	char my_char_array[] = "abc";std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;

上面这两行代码,在调用funcsum()时,第1个类型模板参数T被推断为char类型,第2个类型模板参数U就变成了SumFixedTraits类型。因此,funcsum()函数模板中的代码行:

typename U::sumT sum = U::initValue();

等价于:

typename SumFixedTraits<char>::sumT sum = SumFixedTraits<char>::initValue();

等价于:

int sum = 0;

也就是说,计算和值的时候,用于保存和值的sum变量int类型。如果希望用于保存和值的sum变量int类型变成__int64类型,怎么做呢?也是可以做到的,这就是引入类型模板参数U的灵活之处。
将代码行:

std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;

修改为:

std::cout << (int)(funcsum<char, SumFixedTraits<int>>(&my_char_array[0], &my_char_array[2])) << std::endl;

如果需要,还可以把funcsum()的第2个类型模板参数指定为一个完全不同的trait类模板,这完全由程序员自己决定。

完整代码,如下:

#include "killCmake.h"#include<string>using namespace std;template<typename T>
struct SumFixedTraits;template<>
struct SumFixedTraits<char>
{using sumT = int;static sumT initValue() {return 0;}
};template<>
struct SumFixedTraits<int>
{using sumT = __int64;static sumT initValue() {return 0;}
};template<>
struct SumFixedTraits<double>
{using sumT = double;static sumT initValue() {return 0.0;}
};template<typename T,typename U = SumFixedTraits<T>>
auto funcsum(const T* begin, const T* end)
{// using sumT = typename SumFixedTraits<T>::sumT;  本行不需要// sumT sum = SumFixedTraits<T>::initValue();  本行不需要typename U::sumT sum = U::initValue();for (;;){sum += (*begin);if (begin == end)break;++begin;}return sum;
}int main()
{char my_char_array[] = "abc";std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;std::cout << (int)(funcsum<char, SumFixedTraits<int>>(&my_char_array[0], &my_char_array[2])) << std::endl;return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Proteus仿真--基于DAC0808设计的直流电机调速器

本文介绍基于DAC0808设计的直流电机调速器设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 设置按键A-H按键&#xff0c;每个按键分别对应不同的速度&#xff0c;按下后电机按照设定速度转动 仿真图如下 仿真运行视频 Proteus仿真--基于DAC0808设计的直流电机调…

互联网数据传输原理 |OSI七层网络参考模型

网络模型 OSI 网络参考模型&#xff0c;仅作为参考&#xff0c;也就是说OSI网络实际中并不使用。我们只是把OSI网络模型作为参考&#xff0c;在网络出现问题的时候&#xff0c;可以从一个宏观的整体去分析和解决问题。而且搭建网络的时候也并不一定需要划分为7层 但是当今互联…

【uniapp】小程序中input输入框的placeholder-class不生效解决办法

问题描述 uniapp微信小程序&#xff0c;使用input组件时&#xff0c;想要改变提示词 placeholder 的样式&#xff0c;但是使用placeholder-class 改变不了 如下&#xff1a; <input type"text" placeholder"搜索" placeholder-class"placeholde…

2024最新金三银四软件测试面试题

一直以来大大小小参与过不少面试&#xff0c;遇到过不少坑&#xff0c;但是没来的及好好总结汇总下。现在把之前遇到的问题汇总下&#xff0c;希望以后自己能加深印象。 1、appium 怎么定位toast弹框 appium1.6以后回答需要升级u2进行定位。 2、什么是事务&#xff0c;知道事…

PADS9.5封装库转换为AD库

1、打开PADS Layout&#xff0c;File – Library&#xff0c;选中usr&#xff0c;如下图&#xff1a; 2、封装– 导入&#xff0c;选中你的 .d后缀文件(也就是PADS的封装文件)&#xff0c;打开。 3、元件 – 新建 – PCB封装 - 分配 - 确定。 4、&#xff0c;选择“斜线”…

Laya2.13.3接入第三方库Socket.io

服务端&#xff1a; 1.新建一个文件夹&#xff0c;使用npm.init -y创建node工程 2.在控制台使用以下代码下载Socket.io npm install socket.io 3.创建一个app.js的文件&#xff0c;将以下代码填入 import { Server } from "socket.io"; import { createServer }…

Linux学习笔记3 xshell(lnmp)

xshell能连接虚拟机的前提是真机能够ping通虚拟机网址 装OpenSSL依赖文件 [rootlocalhost nginx-1.12.2]# yum -y install openssl pcre-devel 依赖检测[rootlocalhost nginx-1.12.2]# ./configure [rootlocalhost nginx-1.12.2]# yum -y install zlib [rootlocalhost n…

【腾讯云 HAI域探秘】StableDiffusionWebUI 让我找到了宫崎骏动漫里的夏天

目录 前言一、HAI二、应用场景三、构建 Stable Diffusion 模型1、新建HAI应用2、StableDiffusionWebUI&#xff08;1&#xff09;功能介绍&#xff08;2&#xff09;页面转中文&#xff08;3&#xff09;AI绘图① 正向提示词语② 反向提示词③ “” 、“ AND”、“|” 用法④ 权…

自定义函数参数传递问题

最近&#xff0c;被一个函数调用参数传递的问题困惑了一阵。自己写的解释程序&#xff0c;一直用的好好的。在暗自得意的过程中&#xff0c;突然出现了bug&#xff0c;被泼了一头冷水。当然&#xff0c;bug是在无意中被发现的&#xff0c;确定以后则可以编制专用的代码来揭示它…

重积分的应用@物体对外部质点的引力问题

文章目录 引力(*)分析两质点间的引力公式三重积分计算引力薄片情形计算例 引力(*) 这里讨论的是:空间一物体对于物体外一点 P 0 ( x 0 , y 0 , z 0 ) P_{0}(x_0,y_0,z_0) P0​(x0​,y0​,z0​)处单位质量的质点的引力 分析 仍然使用元素法, 设占有空间有界闭区域 Ω \Omega …

网络协议与 IP 编址

网络协议与 IP 编址 之前大概了解过了网络的一些基础概念&#xff0c;见文章&#xff1a; 网络基础概念。 之前简单了解OSI模型分层&#xff1a; TCP/IP模型OSI模型TCP/IP对等模型应用层应用层表示层应用层会话层主机到主机层传输层传输层因特网层网络层网络层网络接入层数据链…

jsonwebtoken生成token和解析

先上npm地址 jsonwebtoken&#xff1a;jsonwebtoken - npm express-jwt&#xff1a;express-jwt - npmps const express require(express); const jwt require(jsonwebtoken); const { expressjwt: expressJWT} require(express-jwt)const app express();// 设置密钥 co…

爱智EdgerOS之深入解析数据库模块的Redis Client

一、Redis 简介 无论是什么类型的应用&#xff0c;都少不了和数据打交道。尤其是一些复杂的应用场景&#xff0c;都少不了一个高效可靠的数据库。例如日常开发中最常见的 MySQL 等关系型数据库&#xff0c;让数据的存储、检索轻松简单起来&#xff0c;甚至可以轻松地处理百万量…

51单片机c语言烧录软件,51单片机烧写程序的方法

STC89C51是应用广泛的51单片机&#xff0c;很多人都是通过该单片机入门学习的&#xff0c;单片机的学习需要勤动手。单片机需要烧写程序&#xff0c;要用到相关的软件和硬件。下面介绍一下51单片机烧写程序的方法。 1 所用到的硬件工具 51单片机烧写程序需要用到单片机的UART…

C语言数组(下)

我希望各位可以在思考之后去看本期练习&#xff0c;并且在观看之后独立编写一遍&#xff0c;以加深理解&#xff0c;巩固知识点。 练习一&#xff1a;编写代码&#xff0c;演⽰多个字符从两端移动&#xff0c;向中间汇聚 我们依旧先上代码 //编写代码&#xff0c;演⽰多个字…

数据库Delete的多种用法

数据库的Delete操作是用来删除数据库中的数据记录的&#xff0c;它是数据库操作中的一种重要操作&#xff0c;能够帮助用户删除不需要的数据&#xff0c;以便保持数据库的整洁和高效。在使用Delete操作时&#xff0c;需要注意确保操作的准确性和安全性&#xff0c;以免误删重要…

基于 Gin 的 HTTP 中间人代理 Demo

前面实现的代理对于 HTTPS 流量是进行盲转的&#xff0c;也就是说直接在 TCP 连接上传输 TLS 流量&#xff0c;但是我们无法查看或者修改它的内容。当然了&#xff0c;通常来说这也是不必要的。不过对于某些场景下还是有必要的&#xff0c;例如使用 Fiddler 进行抓包或者监控其…

触想嵌入式工业一体机在智能垃圾分类站的应用

1、行业发展背景 根据住建部给出的目标&#xff0c;到2025年前&#xff0c;全国地级及以上城市要基本建成垃圾分类处理系统。随着垃圾分类政策在全国强制落地&#xff0c;终端执行层面面临的最迫切问题是垃圾分类的准确性与社会参与意愿&#xff0c;而这两点与垃圾分类操作的简…

CNN发展史脉络 概述图整理

CNN发展史脉络概述图整理&#xff0c;学习心得&#xff0c;供参考&#xff0c;错误请批评指正。 相关论文&#xff1a; LeNet&#xff1a;Handwritten Digit Recognition with a Back-Propagation Network&#xff1b; Gradient-Based Learning Applied to Document Recogniti…

Python 中的数学运算(Python Math)

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python中的math模块是数学运算的重要工具&#xff0c;提供了丰富的数学函数和常数。本文将深入探讨math模块的功能和用法&#xff0c;使您能够更好地利用Python进行数学运算。 Python的math模块是一个强大的工具…