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

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.lryc.cn/news/255158.html

相关文章:

  • BUUCTF-[GYCTF2020]FlaskApp flask爆破pin
  • web前端实现LED功能、液晶显示时间、数字
  • YOLOv8改进 | 2023 | DiverseBranchBlock多元分支模块(有效涨点)
  • Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
  • kubeadm 安装k8s1.28.x 底层走containerd 容器
  • “分割“安卓用户,对标iOS,鸿蒙崛起~
  • 【Vulnhub 靶场】【hacksudo: ProximaCentauri】【简单 - 中等】【20210608】
  • share pool的组成
  • 应用案例 | 基于三维视觉的汽车零件自动化拧紧解决方案
  • Redis server启动源码
  • C++基础 强制转换
  • 【python、opencv】opencv仿射变换原理及代码实现
  • mac本地部署stable-diffusion
  • dockers安装rabbitmq
  • 07、pytest指定要运行哪些用例
  • springboot集成cxf
  • 快速认识什么是:Kubernetes
  • YOLOv6 学习笔记
  • paypal贝宝怎么绑卡支付
  • 活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新
  • Vue 循环走马灯
  • <Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(3)》(27)
  • 【华为数据之道学习笔记】3-2 基础数据治理
  • GO设计模式——7、适配器模式(结构型)
  • Java实现TCP一对一通信,实现UDP群聊通信
  • Vue + Element 实现按钮指定间隔时间点击
  • UE Websocket笔记
  • STM32h7 接收各种can id情况下滤波器的配置
  • 《深入理解计算机系统》学习笔记 - 第三课 - 浮点数
  • 总结:服务器批量处理http请求的大致流程