[C++] traits机制

文章目录

  • C++之type_traits
    • is_floating_point<T> ..的使用
    • std::enable_if<T>::type的使用
    • std::remove_cv
  • 如何自定义traits

C++之type_traits

is_floating_point …的使用

  • 一般在定义打印模板函数的时候,当我们用printf进行终端日志打印,需要根据打印的类型来设置flag,所以这个时候判断数据类型就很必要了, 我们可以根据is_same,is_float_point, is_integral等来确定类型情况。可以参考cuda打印实例
 std::is_floating_point<yourtype>::value;std::is_same<type1, type2>::value;
  • 这些is_xxx的函数,如何定义的; 有什么可以学习的点

std::enable_if::type的使用

  • c++的原则就替换失败并非错误(SFINAE)。std::enable_if 就是满足条件时类型是有效的
  • 所谓的SFINAE规则就是在编译时进行查找替换,对于重载的函数,如果能够找到合适的就会替换,如果第一个不合适并不会报错,而会使用下一个替换直到最后一个,如果都不满足要求,那么才会报错。出现二义性的话也会报错。
  • 主要两个应用
  • 类型判断,可以自定义类型判断
//判断类型
template <typename _Tp>
struct Smart_pointer : public false_type {};template <typename _Tp>
struct Smart_pointer<std::weak_ptr<_Tp>> : public true_type {};template <typename _Tp>
struct Smart_pointer<std::shared_ptr<_Tp>> : public true_type {};template <typename _Tp>
struct is_smart_pointer : public Smart_pointer<typename std::remove_cv<_Tp>::type>{};template <typename _Tp>
typename enable_if<is_smart_pointer<_Tp>::value,void>::type check(_Tp p){std::cout << "is smart pointer" << std::endl;
}
template <typename _Tp>
typename enable_if<!is_smart_pointer<_Tp>::value,void>::type check(_Tp p){std::cout << "not smart pointer" << std::endl;
}
void test_enable_if(){int *p = new int(3);std::shared_ptr<int> sp = std::make_shared<int>(3);check(sp);check(p);delete p;
}
  • 返回值指定,根据输入类型判断返回值
template <typename _Tp>typename enable_if<std::is_integral<_Tp>::value,bool>::type is_odd(_Tp i){return i&0x1;}void test_is_odd(){std::cout << std::boolalpha << is_odd(10) << std::endl;}
  • Apollo开源代码中的一个实例; 利用C++的SFINAE原则,实现在类的继承过程中,上层类中定义一个必执行的函数,里面调用子类可能实现可能不实现的具体函数,这个时候就用到了这个特性,通过模板推导机制,实现子类定义这个具体操作时,这个必执行的函数会调用这个具体操作,当没有定义是,就按照这个必执行函数的默认操作去执行。

  • Apollo 开源代码示例分析-HasShutdown

#include <type_traits>
#include <utility>// apollo: cyber/base/macros.h
#define DEFINE_TYPE_TRAIT(name, func)                     \template <typename T>                                   \struct name {                                           \template <typename Class>                             \static constexpr bool Test(decltype(&Class::func)*) { \return true;                                        \}                                                     \template <typename>                                   \static constexpr bool Test(...) {                     \return false;                                       \}                                                     \\static constexpr bool value = Test<T>(nullptr);       \};                                                      \\template <typename T>                                   \constexpr bool name<T>::value;// apollo: cyber/common/macros.h
/**
template <typename T>
struct HasShutdown {template <typename Class>static constexpr bool Test(decltype(&Class::Shutdown)*) {return true;}template <typename>static constexpr bool T(...) {return false;}static constexpr bool value = Test<T>(nullptr);
};
template <typename T>
constexpr bool HasShutdown<T>::value;*/
DEFINE_TYPE_TRAIT(HasShutdown, Shutdown)template <typename T>
typename std::enable_if<HasShutdown<T>::value>::type CallShutdown(T *instance) {instance->Shutdown();
}template <typename T>
typename std::enable_if<!HasShutdown<T>::value>::type CallShutdown(T *instance) {(void)instance; // 可以自定义任何默认的动作。
}/** 分析
1. 当instance实例的类中有Shudown时,第一个模板中HasShutdown<T>::value是true,则enable_if<true>::type是合法的;则第一个模板函数被匹配;而此时!HasShutdown<T>::value是false,则第二个模板函数匹配有问题,所以根据C++的SFINAE原则,则第一个被推导出来;所以当调用CallShutdown时,第一个函数被调用,而其有会调用instance中的shutdown函数。
3. 反之,当instance中没有shutDown,则第一个的HasShutdown<T>::value是false,则std::enable_if<HasShutdown<T>::value>::type非法,所以第一个模板不能被推导出来,而第二个模板被推导出来,所以当调用CallShutdown时,第二个函数形式被调用;从而这就实现了,当有Shutdown的时候调用自己定义的,否则不做任何事情。
*/// 下面是CallShutdown被使用时的场景, 通过在一个单例中cleanup里调用,来实现用户定制或不定制的情况。
#define DECLARE_SINGLETON(classname)                                      \public:                                                                  \static classname *Instance(bool create_if_needed = true) {              \static classname *instance = nullptr;                                 \if (!instance && create_if_needed) {                                  \static std::once_flag flag;                                         \std::call_once(flag,                                                \[&] { instance = new (std::nothrow) classname(); }); \}                                                                     \return instance;                                                      \}                                                                       \\static void CleanUp() {                                                 \auto instance = Instance(false);                                      \if (instance != nullptr) {                                            \CallShutdown(instance);                                             \}                                                                     \}                                                                       \\private:                                                                 \classname();                                                            \DISALLOW_COPY_AND_ASSIGN(classname)

std::remove_cv

  • 去掉变量的const, volatile属性,获取其原始类型信息。

实现方式

  • 模版推导丢弃const和volatile参数。

性能开销

  • 模版推导完成操作,不涉及运行时开销。

调用stl

  • remove_const
  • remove_volatile

作者:i_need_job
链接:https://www.jianshu.com/p/a771299d3a89
来源:简书

如何自定义traits

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

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

相关文章

OpenCV 视频处理与保存

一、知识点 1、VideoCapture类 (1)、用于从视频文件、摄像机或图像序列中捕获视频帧。 (2)、构造函数 VideoCapture(const String & filename, int apiPreference CAP_ANY) a、filename可以是视频文件的名称(例如"video.avi")&#xff0c;可以是图…

【Leetcode】字符串之二进制求和、字符串相乘

文章目录 算法原理二进制求和题目链接题目描述解题思路代码 字符串相乘题目链接题目描述解题思路代码 算法原理 这两道题都是属于算法里一种经典题型&#xff1a;高精度加/减/乘/除法&#xff0c;需要我们模拟加/减/乘/除 列竖式运算。 二进制求和 题目链接 题目链接 题目描…

MongoDB:索引

目录 1、索引数据结构&#xff1a;B-树 2、索引类型 2.1 单字段索引 2.2 复合索引&#xff08;最重要&#xff01;&#xff09; 2.3 多键索引&#xff08;数组字段&#xff09; 2.4 地理空间索引 2.5 全文索引 2.6 哈希索引&#xff08;分片专用&#xff09; 2.7 TTL …

【大模型】Transformer架构完全解读:从“盲人摸象“到“通晓万物“的AI进化论

&#x1f916; Transformer架构完全解读&#xff1a;从"盲人摸象"到"通晓万物"的AI进化论 —— 一位大模型探索者的技术日记 ☕ 第一章&#xff1a;为什么说Transformer是AI界的"蒸汽机革命"&#xff1f; 1.1 从RNN到Transformer&#xff1a;…

JavaEE:使用JMeter进行接口并发测试

一、下载与安装&#xff1a; 1.下载apache-jmeter-5.6.3.zip&#xff1a; https://jmeter.apache.org/download_jmeter.cgi 2.解压到D:\Program Files\apache-jmeter-5.6.3目录 3.添加JDK环境配置到D:\Program Files\apache-jmeter-5.6.3\bin\jmeter.bat文件开头&#xff1…

【笔记】MSYS2 的 MinGW64 环境中正确安装 Python 相关环境管理工具 (Poetry、Virtualenv、Pipenv 和 UV)

MSYS2 环境配置与 Python 项目依赖管理笔记_msys更新python-CSDN博客 【技术笔记】MSYS2 指定 Python 版本安装方案_pacman -u 安装指定版本-CSDN博客 更多关于 MSYS2 开发环境的配置&#xff0c;请查看往期笔记。 简介 本笔记将记录我们在 MSYS2 的 MinGW64 环境中安装 Pytho…

ubuntu添加域名解析服务器地址

在 Ubuntu 中配置域名解析主要有两种方式&#xff1a;静态修改 /etc/hosts 文件 和 动态修改 DNS 解析服务器配置。以下是详细操作指南&#xff1a; 建议优选:二、永久方案&#xff1a;修改 DNS 解析服务&#xff08;推荐&#xff09;中的方法1 一、临时方案&#xff1a;修改…

通过 AIOps 、生成式 AI 和机器学习实现更智能的可观测性

支持 AIOps 的理由 人工智能运维&#xff08;AIOps&#xff09;是将人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和分析技术应用于提升 IT 运维团队日常工作的过程。简单来说&#xff0c;AIOps 是软件系统通过 AI 和 ML 以及相关分析技术来简化和…

【DataWhale组队学习】AI办公实践与应用

AI办公-PPT制作 1. 使用大模型制作PPT的常见流程 使用大模型生成PPT的文稿将文稿的内容喂给可以直接生成PPT的大模型&#xff0c;生成PPT 2. 使用大模型生成PPT文稿 我们可以先使用上一章提过的那些大模型去生成一个PPT的文稿。那根据上一章的内容&#xff0c;我们想要去让…

人机融合智能 | 人智交互中的机器行为设计与管理

以人工智能为代表的科学技术正在深入地塑造和改变着人类的社会、文化和经济等,在“无所不在的算法与智能”的时代,了解智能机器的行为对于设计智能行为并使其造福于人类,对于智能机器的设计者、开发者和使用者,都具有重要意义。机器行为研究从学科交叉的视角,将智能机器行为置于…

langChainv0.3学习笔记(高级篇)

目录 工具创建工具从函数创建工具tool 装饰器结构化工具 从可运行对象创建工具子类化 BaseTool如何创建异步工具处理工具错误返回工具执行的artifact 使用内置工具和工具包自定义默认工具如何使用内置工具包 使用聊天模型调用工具定义工具模式Python 函数LangChain 工具Pydanti…

UiAutomator2 与 Appium 对比分析:安卓自动化测试框架的选择指南

目录 一、基础介绍UiAutomator2Appium 二、功能对比三、架构差异UiAutomator2 架构简图&#xff1a;Appium 架构简图&#xff1a; 四、使用场景分析五、优缺点总结UiAutomator2 优点&#xff1a;UiAutomator2 缺点&#xff1a;Appium 优点&#xff1a;Appium 缺点&#xff1a; …

缺失的第一个正整数

继续每日一题 今天给大家带来一道将数组视为哈希表的算法 题目描述&#xff1a; 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 题目示例&#xff1a; 由于题目要求…

单例模式-Python示例

单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是设计模式中一种创建型模式&#xff0c;广泛应用于软件开发中。一以下以故事化的方式&#xff0c;结合详细的技术讲解&#xff0c;介绍单例模式的背景、定义、适用场景&#xff0c;并提供python的示例代码。 故事…

啥是 SaaS

https://www.youtube.com/watch?vnpcL7oRZQlI这个视频讲了什么东西&#xff0c; 什么 idea?好的&#xff0c;这个视频内容非常棒&#xff0c;信息量很足。下面为你详细总结视频讲了什么&#xff0c;以及核心的 Idea 是什么。 视频核心 Idea 这个视频讲的是一位名叫 Leandro…

Spring Boot 工程启动以后,我希望将数据库中已有的固定内容,打入到 Redis 缓存中,请问如何处理?

在 Spring Boot 工程中&#xff0c;将数据库中的固定内容预先加载到 Redis 缓存中可以通过以下步骤实现。这里假设你已经配置好了 Spring Data Redis 和数据库&#xff08;如 MySQL&#xff09;的连接。 1. 添加依赖 首先&#xff0c;确保你的 pom.xml&#xff08;Maven&…

springboot企业级项目开发之项目测试——集成测试!

集成测试 集成测试是指项目代码在单元测试完成后进行的第二阶段测试。集成测试的重点是在集成组件或单元之间交互时暴露缺陷&#xff0c;以保证不同模块之间相互调用的正确性。在Spring Boot的项目集成测试中&#xff0c;将测试Controller和Dao的完整请求处理。应用程序在服务…

HTML 媒体(Media)

HTML 媒体&#xff08;Media&#xff09; 引言 HTML 媒体元素是构成现代网页的重要组成部分&#xff0c;它允许我们在网页中嵌入各种类型的媒体内容&#xff0c;如音频、视频、图像等。这些元素不仅丰富了网页的视觉效果&#xff0c;还提升了用户体验。本文将详细介绍 HTML 媒…

轻量化分布式AGI架构:基于区块链构建终端神经元节点的互联网智脑

一、架构概述 该架构通过将终端设备&#xff08;如手机、IoT设备&#xff09;转化为神经元节点&#xff0c;结合区块链技术构建去中心化智能网络&#xff0c;形成“互联网智脑”。其核心在于突破传统AGI算力瓶颈&#xff0c;实现数据安全共享与价值分配。 1.1 关键特征 分布…

【知识图谱构建系列6】:借了张显卡先跑着

文章目录 前情提要mistral模型运行代码前情提要 之前咱对LLM4KGC的代码稍作修改,目标是用modelscope来下载模型。 现在这个代码终于能跑了。 前面咱说,我们的显卡只有6G的显存。现在呢,我也成功借到了A100的显卡。这下,咱可以先跑跑这个项目默认带的mistral模型。 mist…