学习模板元编程(2)std::true_type/false_type

目录

实现原理

应用场景

条件编译

通过特化和继承,实现std::is_xxx系列

思路

举例

例子1,is_bool

例子2,is_ptr


实现原理

std::true_type/false_type是模板intergral_constant的两种实现:

using true_type = integral_constant<bool, true>;
using false_type = integral_constant<bool, false>;

应用场景

条件编译

先看一个不使用true_type/false_type,结果编译失败的例子。

编程者的用意是通过一个布尔型变量,配合一个模板类型参数T,控制类的行为:

#include <iostream>template<class T, bool b>
class fail
{
public:T a;fail(){if (b){a = 10;std::cout << a << std::endl;}else{a = "10";std::cout << a << std::endl;}}
};
int main(void)
{fail<int, true> f;std::cin.get();return 0;
}

编译失败:

诚然,a="10"这个分支是不会在运行时命中的,但是这个分支仍会在编译时被编译。而a是个整型(因为fail<int, true>) ,所以给整型赋值字符串将导致编译失败。

从上面的分析可以看出,运行时仍然保留了两个条件分支,是编译失败的原因。

现在使用std::true_type/false_type,让编译时就命中条件分支,并进行有选择的编译,避免语法错误

#include <iostream>
//注:这里使用vs2013,而bool_constant是C++17标准引入的,所以这里手动定义
template<bool val>
using bool_constant = std::integral_constant<bool, val>;template<class T, bool b>
class fail
{
public:T a;fail(){
//注:这里一定要有(),
//否则func函数的输入参数就是一个类型bool_constant<b>,而不是一个变量
//而类型不能作为输入参数func(bool_constant<b>());}void func (std::true_type t){a = 10;std::cout << a << std::endl;}void func(std::false_type f){a = "10";std::cout << a << std::endl;}
};
int main(void)
{fail<int, true> f;std::cin.get();return 0;
}

编译通过,且正常运行:

这里采用的是模板匹配的办法,没有直接用true/false命中条件分支,而是先通过true/false实现bool_constant的具体类型(true_type/false_type)。利用类型的区别来匹配合适的func()。

具体实现时,要注意两点:

1 要用func(bool_constant<b>()),而不是func(bool_constant<b>),因为bool_constant<b>只是个类型,不是变量,不能作为输入参数;

2 两个func()函数定义的时候(func(std::true_type), func(std::false_type)),里面还指明了具体的变量名(t,f)。其实也可以不指明变量名,因为这两个变量在函数体内没有用到,也不会因为没有变量名就影响匹配。

通过特化和继承,实现std::is_xxx系列

思路

先假定被判断的类型“不是”定义一个模板,既然不是,就继承false_type,然后再特化之,定义“是”的情况,既然是,就继承true_type。

举例

例子1,is_bool
#include <iostream>template<class T>
struct is_bool : std::false_type
{};template<>
struct is_bool<bool> : std::true_type
{};int main(void)
{std::cout << is_bool<int>() << std::endl;std::cout << is_bool<bool>() << std::endl;std::cin.get();return 0;
}

结果:

 至于为什么cout可以直接输出is_bool<int/bool>(),它又不是一个简单的布尔型,而是一个自定义的结构体?那是因为类型转换函数的结果,参见类型转换运算符(conversion operator)-CSDN博客

例子2,is_ptr

代码:

#include <iostream>template<class T>
struct is_ptr : std::false_type
{};template<class T>
struct is_ptr<T *> : std::true_type
{};int main(void)
{std::cout << is_ptr<int>() << std::endl;std::cout << is_ptr<int *>() << std::endl;std::cin.get();return 0;
}

结果:

关于模板如何匹配到指针,那是因为模板匹配的原则是匹配与当前情况最贴切的模板。参看我前面的博客初尝类型萃取--typename、模板偏特化、和traits之(二)模板偏特化-CSDN博客

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

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

相关文章

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models论文阅读笔记

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 摘要 本文探索了思维链&#xff08;chain of thought&#xff09;&#xff0c;即一系列中间推理过程&#xff0c;可以有效地增强大语言模型的复杂推理能力。 在三个大型语言模型上的实验表明&#xff0…

华为核心交换机S7700的内存OID

华为S7700系列交换机 SNMP内存相关OID说明 以下列出了华为S7700核心交换机在SNMP v2c下可用的内存相关OID,包括CPU内存利用率、物理内存总量、已用内存和空闲内存,并给出每个OID的功能描述、数据类型、单位、使用说明等信息。 1. CPU内存利用率(处理器内存占用百分比) OID名…

中州养老Day02:服务管理护理计划模块

本日任务:服务管理的后端开发 1.学习:护理项目 (1)评估开发工期的思路和注意事项 全面熟悉项目,了解项目重点,设置开发优先级 比如,在下面图片的接口文档中版本有1.0,2.0,3.0也就是功能的初代,二代,三代,所以我们在大致浏览所有功能后,要优先关注初代功能的实现 开发计划 …

JavaScript:Ajax(异步通信技术)

一、Ajax 核心概念Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种异步通信技术&#xff0c;核心特点&#xff1a;无刷新更新&#xff1a;无需重新加载整个页面异步处理&#xff1a;后台发送/接收数据不阻塞用户数据格式&#xff1a;支持 XML/JSON/HTML/纯…

leetcode 118. 杨辉三角 简单

给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。示例 1:输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2:输入: numRows 1 输出: [[1]]提示:1 < numRows…

jmeter--While控制器--循环直到接口响应符合条件

场景描述业务场景&#xff1a;单据计算接口情况&#xff1a;单据计算&#xff0c;调用接口1发起计算&#xff0c;接口2查询计算执行结果jmeter脚本&#xff1a;把接口1和接口2&#xff08;接口2循环调用&#xff0c;直到返回执行完成状态&#xff09;添加到一个事务&#xff0c…

组播 | 不同 VLAN 间数据转发实现逻辑 / 实验

注&#xff1a;本文为 “不同 vlan 间组播数据转发” 相关合辑。 图片清晰度受引文原图所限。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 组播 VLAN&#xff1a;解决路由器为不同 VLAN 用户复制多份流量问题 aiaiai010101 于 2018-11-16 22:42:06 发布 一、组…

渗透测试常用指令

互联网设备的开放信息查询网站&#xff1a; https://fofa.info/ https://www.zoomeye.org/ https://quake.360.net/quake/#/index https://x.threatbook.com/v5/mapping https://hunter.qianxin.com/ 目录 一、网络探测与扫描 traceroute whatweb ping fping nc n…

51单片机串行通信的设计原理有哪些?

51单片机是指由美国INTEL公司生产的一系列单片机的总称&#xff0c;这一系列单片机包括了许多品种&#xff0c;如8031&#xff0c;8051&#xff0c;8751&#xff0c;8032&#xff0c;8052&#xff0c;8752等&#xff0c;其中8051是最早最典型的产品&#xff0c;该系列其它单片机…

设计模式十四:适配器模式(Adapter Pattern)

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;用于将一个类的接口转换成客户端期望的另一个接口&#xff0c;使原本不兼容的类可以一起工作。适配器模式的类型类适配器&#xff08;通过多重继承实现&#xff09;对象适配器&#xff08;通…

力扣经典算法篇-38-组合(回溯算法)

1、题干 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 示例 2&#xff1a; 输入&#xff1a;…

多人命题系统

目 录 摘 要 Abstract 1 系统概述 1.1 概述 1.2课题意义 1.3 主要内容 2 系统开发环境 2. 1 JAVA简介 2. .2 B/S架构 2.3 SSM三大框架 2.4访问数据库实现方法 2.5 系统对MySQL数据库的两种连接方式 3 需求分析 3.1技术可行性&#xff1a;技术背景…

UDP_千兆光通信(四)Tri Mode Ethernet MAC ip核

Tri Mode Ethernet MAC ip核使用与例程分析 一、 Tri Mode Ethernet MAC ip核功能 二、 Tri Mode Ethernet MAC ip核配置 数据传输速率 主要设置接口 帧滤波功能选择,以及流控选择 三、 Tri Mode Ethernet MAC ip核使用 3.1 ip核接口 3.2 ip核接口说明 3.2.1 tx_ifg_delay 3.2…

Linux网络:多路转接 epoll

Linux网络&#xff1a;多路转接 epoll一、epoll三个接口函数1、epoll_create2、epoll_ctl3、epoll_wait二、epoll的工作原理三、epoll的echo_server1、EpollServer类2、构造函数3、事件循环4、事件派发5、事件处理6、测试四、LT和ET模式1、LT2、ET五、项目代码一、epoll三个接口…

uniapp 微信小程序 列表点击分享 不同的信息

<button open-type"share" plain class"item share" click.stop"shareFn(item)"><text>分享</text> </button>import {onShareAppMessage} from dcloudio/uni-applet shareObj ref({})// 将点击后的分享设置信息 关键…

C# 匿名方法详解

C# 匿名方法详解 引言 在C#编程语言中,匿名方法是使用Lambda表达式创建的没有名称的方法。它们在LINQ查询、事件处理和其他场合中非常有用。本文将详细介绍C#匿名方法的基本概念、语法、使用场景以及优势。 匿名方法的概念 匿名方法是一种无需显式定义名称的方法。在C#中,…

SD卡简介与驱动开发

基本概念 存储卡有很多种类&#xff0c;CF卡、记忆棒、SD卡、XD卡、MMC卡、MS卡、TF卡、MicroSD卡等。平时最常见的有SD卡和MicroSD卡两种&#xff0c; SD卡和MicroSD只是两张卡的大小不同&#xff0c;规格版本是完全相同的&#xff0c;均由SD卡协会推出。 SD卡有不少规范&…

大数据平台数仓数湖hive之拉链表高效实现

对于缓慢变化的维度表&#xff0c;如客户表&#xff0c;员工表&#xff0c;为了不丢失历史数据&#xff0c;又不至于太浪费存储空间&#xff0c;我们采用拉链表实现。 实现过程如下&#xff1a; 1、采集初始数据&#xff1a; 1.1 从mysql导出数据到hdfs /data/dolphinschedu…

【VSCode】常用插件推荐(持续更新~)

以下的这些插件都有使用过&#xff0c;可取对自己编码有用的选择安装。&#x1f9e0; 智能补全 / 提示类插件 1. Auto Import在编码时选择有对应导入包的选项&#xff0c;自动为 JS/TS 文件中的使用项补全并添加 import 声明&#xff0c;极大提高开发效率。2. Iconify IntelliS…

ICML 2025 | 深度剖析时序 Transformer:为何有效,瓶颈何在?

本文介绍帝国理工学院等机构在 ICML 2025 发表的最新研究成果。该研究并未提出新模型&#xff0c;而是对现有时间序列 Transformer 模型进行了一次深刻的拷问——为何结构更简单的 Transformer&#xff08; PatchTST, iTransformer&#xff09;在各大基准测试中&#xff0c;反而…