C++中几个常用的类型选择模板函数
std::enable_if<B, T>::type
如果编译期满足B,那么返回类型T,否则编译报错
std::conditional<B, T, F>::type
如果编译期满足B,那么返回类型T,否则返回类型F
下面是一个示例,展示如何使用 `std::conditional` 来选择返回类型:
#include <iostream>
#include <type_traits>template <typename T, typename U>
auto max(T a, U b) -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U>::type {return (a > b) ? a : b;
}int main() {int a = 5;double b = 3.14;auto result = max(a, b);std::cout << "Max value: " << result << std::endl;return 0;
}
在上面的示例中,`max` 函数使用了 `std::conditional` 来根据两个参数的类型选择返回类型。如果 `sizeof(T) > sizeof(U)`,则返回类型为 `T`,否则返回类型为 `U`。在 `main` 函数中,我们调用 `max` 函数并打印返回值,演示了根据条件选择返回类型的功能。
需要注意的是,`std::conditional` 是一个模板类,它提供了在编译时进行类型选择的能力。它在很多情况下可以用来实现类型萃取(type traits)和条件编译等功能。
std::integral_constant<T, value>
`std::integral_constant<T, value>` 是 C++ 标准库中的一个模板类,用于表示一个编译时常量的包装器。它接受两个参数:`T` 表示常量的类型,`value` 表示常量的值。
`std::integral_constant<bool, B>` 表示一个固定的(常量)布尔值,其类型为 `bool`,值为 `B`。
下面是一个示例,展示如何使用 `std::integral_constant` 来表示编译时的布尔常量:```cpp
#include <iostream>
#include <type_traits>int main() {std::integral_constant<bool, true> true_value;std::integral_constant<bool, false> false_value;std::cout << "true_value: " << true_value << std::endl;std::cout << "false_value: " << false_value << std::endl;std::cout << "true_value type: " << typeid(true_value).name() << std::endl;std::cout << "false_value type: " << typeid(false_value).name() << std::endl;std::cout << "true_value value: " << true_value() << std::endl;std::cout << "false_value value: " << false_value() << std::endl;return 0;
}
在上面的示例中,我们创建了 `true_value` 和 `false_value` 两个 `std::integral_constant` 实例,分别表示编译时的 `true` 和 `false` 布尔常量。我们使用 `std::cout` 打印了各个常量的值、类型和调用结果。
需要注意的是,`std::integral_constant<bool, B>` 实际上是一个包装器,它提供了类型信息和调用操作符(函数调用运算符),使得它在使用时可以像一个函数一样进行调用。调用 `std::integral_constant` 对象会返回其持有的常量值。
此外,C++ 标准库中的 `std::integral_constant` 还提供了一系列的成员类型和成员函数,如 `value_type`、`operator()`、`operator bool` 等,用于操作和查询包装的常量。这些成员函数和成员类型可以用于进行类型推导、模板元编程和编译时条件判断等用途。
下面看一个比较难的应用,将类型和自定义的数字联系起来,做一些类型判断:
#include <iostream>
enum class type {none_type,// Integer types should go first,int_type,uint_type,long_long_type,ulong_long_type,int128_type,uint128_type,bool_type,char_type,last_integer_type = char_type,// followed by floating-point types.float_type,double_type,long_double_type,last_numeric_type = long_double_type,cstring_type,string_type,pointer_type,custom_type
};// Maps core type T to the corresponding type enum constant.
template <typename T>
struct type_constant : std::integral_constant<type, type::custom_type> {};#define FMT_TYPE_CONSTANT(Type, constant) \template <> \struct type_constant<Type> \: std::integral_constant<type, type::constant> {}FMT_TYPE_CONSTANT(int, int_type);
FMT_TYPE_CONSTANT(unsigned, uint_type);
FMT_TYPE_CONSTANT(long long, long_long_type);
FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
FMT_TYPE_CONSTANT(bool, bool_type);
FMT_TYPE_CONSTANT(float, float_type);
FMT_TYPE_CONSTANT(double, double_type);
FMT_TYPE_CONSTANT(long double, long_double_type);
FMT_TYPE_CONSTANT(const void*, pointer_type);constexpr bool is_integral_type(type t) {return t > type::none_type && t <= type::last_integer_type;
}
constexpr bool is_arithmetic_type(type t) {return t > type::none_type && t <= type::last_numeric_type;
}int main()
{int a = 12;std::cout<< is_integral_type(type_constant<decltype(a)>::value)<<std::endl; //1bool* b = nullptr;std::cout<< is_integral_type(type_constant<decltype(b)>::value)<<std::endl; //0
}
std::underlying_type<T>::type
`std::underlying_type<T>::type` 是 C++ 标准库中的一个类型转换工具,它用于获取枚举类型 `T` 的底层类型。
`std::underlying_type` 是一个模板类,接受一个类型参数 `T`,它用于表示一个枚举类型。`std::underlying_type<T>::type` 表示枚举类型 `T` 的底层类型。
下面是一个示例,展示如何使用 `std::underlying_type<T>::type` 来获取枚举类型的底层类型:
#include <iostream>
#include <type_traits>enum class MyEnum : unsigned int {Value1,Value2,Value3
};int main() {using UnderlyingType = std::underlying_type<MyEnum>::type;std::cout << "Underlying type of MyEnum: " << typeid(UnderlyingType).name() << std::endl;return 0;
}
在上面的示例中,我们定义了一个枚举类型 `MyEnum`,包含三个枚举值。然后,我们使用 `std::underlying_type<MyEnum>::type` 来获取 `MyEnum` 的底层类型,并将其赋值给 `UnderlyingType` 类型别名。最后,我们使用 `std::cout` 打印底层类型的类型信息。
在这个示例中,我们使用 `std::underlying_type` 来获取 `MyEnum` 的底层类型。`UnderlyingType` 类型别名被推导为 `unsigned int`,这是 `MyEnum` 底层的类型。
`std::underlying_type` 对于在编译时获取枚举类型的底层类型非常有用。它可以用于处理枚举类型的底层值,进行位操作或其他需要底层类型的操作。
std::remove_cv<remove_reference_t<T>>::type
移除类型T的各种限定符。
比如:const、volatile、左值引用T&。
std::is_same<T, T2>::value
std::is_same<T, T2>::value 是 C++ 标准库中的一个类型特性工具,用于检查类型 T 和类型 T2 是否相同。值得注意的是,cv限定符会让类型不同。
#include <iostream>
#include <type_traits>int main() {bool isSame = std::is_same<int, int>::value;std::cout << "isSame: " << isSame << std::endl; // trueisSame = std::is_same<int, double>::value;std::cout << "isSame: " << isSame << std::endl; // falsebool isSame = std::is_same<const int, int>::value;std::cout << "isSame: " << isSame << std::endl; // falseisSame = std::is_same<volatile int, int>::value;std::cout << "isSame: " << isSame << std::endl; // falseisSame = std::is_same<const int, volatile int>::value;std::cout << "isSame: " << isSame << std::endl; // falsereturn 0;
}
std::is_base_of<T, D>::value
`std::is_base_of<compile_string, S>` 是 C++ 标准库中的一个模板类 `std::is_base_of` 的使用,用于检查类型 `S` 是否是类型 `compile_string` 的基类或派生类。
`std::is_base_of` 是一个类型特性(type trait),它提供了一种在编译时判断一个类型是否是另一个类型的基类或派生类的机制。它属于 C++ 类型特性库(type traits library)的一部分,位于 `<type_traits>` 头文件中。
在给定的代码中,`std::is_base_of<compile_string, S>` 用于检查类型 `S` 是否是类型 `compile_string` 的基类或派生类。它返回一个编译时常量值 `true` 或 `false`,表示 `S` 是否是 `compile_string` 的派生类。
具体的使用示例如下:
// A base class for compile-time strings.
struct compile_string {};template <typename S>
struct is_compile_string : std::is_base_of<compile_string, S> {};template <typename S, std::enable_if<is_compile_string<S>::value>::value>
constexpr auto to_string_view(const S& s)-> basic_string_view<typename S::char_type> {return basic_string_view<typename S::char_type>(s);
}
在上面的示例中,我们使用 `std::is_base_of` 来检查 `derived_class` 是否是 `compile_string` 的派生类。根据返回的结果,我们输出相应的信息。
需要注意的是,`std::is_base_of` 是在编译时进行类型检查的,它只能用于判断类型之间的继承关系,而不能用于检查对象之间的关系。
std::declval<T>()
std::declval<S> 是 C++ 标准库中的一个模板函数 std::declval 的使用,用于获取类型 S 的一个虚拟值(引用)。
std::declval 是一个函数模板,它允许在不实际创建对象的情况下,获取一个类型的虚拟值。它位于 <utility> 头文件中。
在给定的代码中,std::declval<S> 用于获取类型 S 的一个虚拟值。它返回一个该类型的右值引用(Rvalue reference)。
std::declval 的主要用途是用于在编译时创建对类型的引用,以便在模板编程中进行类型推断。它通常与 decltype 一起使用,用于声明返回类型或推断表达式的类型。需要注意的是,std::declval 用于创建虚拟值,但不能用于实际访问该值。它主要用于模板元编程中,用于推断类型和进行 SFINAE(Substitution Failure Is Not An Error)。
template <typename S>
struct is_string: std::is_class<decltype(detail::to_string_view(std::declval<S>()))> {};template <typename S, typename = void> struct char_t_impl {};
template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {using result = decltype(to_string_view(std::declval<S>()));using type = typename result::value_type;
};// detail::to_string_view see belowtemplate <typename Char, std::enable_if<is_char<Char>::value)>::value>
inline auto to_string_view(const Char* s) -> basic_string_view<Char> {return s;
}
template <typename Char, typename Traits, typename Alloc>
inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s)-> basic_string_view<Char> {return s;
}
template <typename Char>
constexpr auto to_string_view(basic_string_view<Char> s)-> basic_string_view<Char> {return s;
}
template <typename Char,std::enable_if<!std::is_empty<std_string_view<Char>>::value>::value>
inline auto to_string_view(std_string_view<Char> s) -> basic_string_view<Char> {return s;
}
template <typename S, std::enable_if<is_compile_string<S>::value>::value>
constexpr auto to_string_view(const S& s)-> basic_string_view<typename S::char_type> {return basic_string_view<typename S::char_type>(s);
}
void to_string_view(...);
比如上面,创建了一个虚拟的S对象的引用,用于驱动`detail::to_string_view`模板进行类型推断,从而判断是否可以继续编译。
相关文章:
C++中几个常用的类型选择模板函数
std::enable_if<B, T>::type 如果编译期满足B,那么返回类型T,否则编译报错 std::conditional<B, T, F>::type 如果编译期满足B,那么返回类型T,否则返回类型F 下面是一个示例,展示如何使用 std::condit…...
【LeetCode】1321. 餐馆营业额变化增长
表: Customer ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | | visited_on | date | | amount | int | ------------------------ 在 SQL 中,(custo…...
【网络技术】【Kali Linux】Wireshark嗅探(八)动态主机配置协议(DHCP)
一、实验目的 本次实验使用 Wireshark (“网鲨”)流量分析工具进行网络流量嗅探,旨在初步了解动态主机配置协议(DHCP协议)的工作原理。 二、DHCP协议概述 动态主机配置协议( D ynamic H ost C onfigurat…...
算法29:不同路径问题(力扣62和63题)--针对算法28进行扩展
题目:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角࿰…...
openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位
文章目录 openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位188.1 磁盘满故障引起的core问题188.1.1 问题现象188.1.2 原因分析188.1.3 处理办法 188.2 GUC参数log_directory设置不正确引起的core问题188.2.1 问题现象188.2.2 原因分析188.2.3 处理办…...
kubernetes入门到进阶(5)
目录 镜像仓库:怎么用好docker hub这个宝藏 什么是镜像仓库(Registry) 什么是docker hub 如何在docker hub上挑选镜像 docker hub上进行概念股命名规则是什么 该怎么上传自己的镜像 离线环境该怎么办 小结 镜像仓库:怎么用好docke…...
【字典树Trie】LeetCode-139. 单词拆分
139. 单词拆分。 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入: s "leetcode&q…...
pytest常用的第三方插件介绍
本节介绍了如何安装和使用第三方插件。如果你想要编写自己的插件,请参阅“编写插件”。 通过pip可以轻松安装第三方插件: pip install pytest-NAME pip uninstall pytest-NAME如果已经安装了插件,pytest会自动找到并集成它,无需手…...
【经验】VSCode连接远程服务器(可以使用git管理、方便查看和编辑Linux源码)
1、查看OpenSSH Windows10通常自带OpenSSH不需要安装。 Windows10下检查是否已经安装OpenSSH的方法: 1)按下快捷键Win + X,选择Windows PoweShell(管理员) 2)输入以下指令: Get-WindowsCapability -Online | ? Name -like ‘OpenSSH*’ 3)如果电脑未安装OpenSSH,…...
机器学习-生存分析:如何基于随机生存森林训练乳腺癌风险评估模型?
一、 引言 乳腺癌是女性最常见的恶性肿瘤之一,也是全球范围内女性死亡率最高的癌症之一。据统计,每年全球有超过200万人被诊断为乳腺癌,其中约60万人死于该疾病。因此,乳腺癌的早期诊断和风险评估对于预防和治疗乳腺癌具有非常重要…...
MySQL学习笔记1: 数据库的简单介绍
目录 1. 数据库是什么2. 数据库这一类软件中的一些典型代表2.1. Oracle2.2. MySQL2.3. SQL Server2.4. SQLite (lite 轻量版) 3. 数据库的类型3.1. 关系型数据库3.2. 非关系型数据库 4. 总结 1. 数据库是什么 数据库是一类软件,这一类软件可以用来管理数据…...
【Docker】安装ELK(Docker Compose)
一、创建挂载目录 mkdir -p /docker/elk/elasticsearch/{plugins,data} mkdir -p /docker/elk/logstash 二、给目录授权 chmod 777 /docker/elk/elasticsearch/data 创建logstash配置文件 vim /docker/elk/logstash/logstash.conf input {tcp {mode => "server" h…...
【机器学习:欧氏距离 】机器学习中欧氏距离的理解和应用
【机器学习:欧氏距离 】机器学习中欧氏距离的理解和应用 距离公式二维更高的维度点以外的物体属性欧几里得距离的平方概括历史 在数学中,欧氏距离’是指欧氏空间中任意两点之间的直线距离。这种距离可以通过应用勾股定理来计算,利用两点的笛卡…...
系统安全及应用
1、基本安全措施 1.1、系统账号清理 在Linux系统中,除了用户手动创建的各种账号之外,还包括随系统或程序安装过程而生产的其他大量账号。除了超级用户root之外,其他大量账号只是用来维护系统运作、启动或保持服务进程,一般是不允…...
Danil Pristupov Fork(强大而易用的Git客户端) for Mac/Windows
在当今软件开发领域,团队协作和版本控制是非常重要的方面。在这个过程中,Git成为了最受欢迎的版本控制工具之一。然而,对于Git的使用,一个好的客户端是至关重要的。 今天,我们要为大家介绍一款强大而易用的Git客户端—…...
最新GPT4.0使用教程,AI绘画,ChatFile文档对话总结+GPT语音对话使用,DALL-E3文生图
一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画,文档对话总结DALL-E3文生图,相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚至也可以和…...
【ARM 嵌入式 编译系列 7.2 -- GCC 链接脚本中 DEFINED 函数与 “AT>“ 符号详细介绍】
文章目录 GCC 链接脚本中 DEFINED 函数DEFINED() 函数> (放置在哪个区域)AT> (加载地址) (填充字节) 在链接脚本中,组合示例 GCC 链接脚本中 DEFINED 函数 在 ARM GCC 链接脚本(.ld 文件)中,DEFINED() 是一种内置函数&…...
Linux基础——进程初识(二)
1. 对当前目录创建文件的理解 我们知道在创建一个文件时,它会被默认创建到当前目录下,那么它是如何知道当前目录的呢? 对于下面这样一段代码 #include <stdio.h> #include <unistd.h>int main() {fopen("tmp.txt", …...
国科大图像处理2024速通期末——汇总2017-2019、2023回忆
国科大2023.12.28图像处理0854期末重点 图像处理 王伟强 作业 课件 资料 一、填空 一个阴极射线管它的输入与输出满足 s r 2 sr^{2} sr2,这将使得显示系统产生比希望的效果更暗的图像,此时伽马校正通常在信号进入显示器前被进行预处理,令p…...
编程笔记 html5cssjs 026 HTML输入类型(2/2)
编程笔记 html5&css&js 026 HTML输入类型(2/2) 输入类型:date输入类型:color输入类型:range输入类型:month输入类型:week输入类型:time输入类型:datetime输入类型…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
