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

C++ 模板元编程 type_traits

C++ 模板元编程 type_traits

  • 一、type_traits 中的常用判断方式
  • 二、is_same比较的一些案例
    • 1.add_lvalue_reference,add_rvalue_reference
    • 2.remove_const,add_const
  • 三、conditional
  • 四、decay
  • 五、enable_if
    • 1.简单使用:
    • 2.举一反三:


一、type_traits 中的常用判断方式

为了之后我们的例子,先创建一些测试的类型

class TestClass
{};class FTestStruct
{};enum MyEnum : char
{ETest1,ETest2,
};class FInterface
{virtual void Init() = 0;};class ChilClass : public FInterface
{virtual void Init() override{}
};

开始对常用的方法进行逐一测试

int main()
{std::cout << "========is_same=======" << std::endl;std::cout << std::is_same<int, int>::value << std::endl;std::cout << std::is_same<int, float>::value << std::endl;std::cout << "========is_class=======" << std::endl;std::cout << std::is_class<TestClass>::value << std::endl;std::cout << std::is_class<FTestStruct>::value << std::endl;std::cout << "========is_enum=======" << std::endl;std::cout << std::is_enum<MyEnum>::value << std::endl;std::cout << "========is_integral=======" << std::endl;std::cout << std::is_integral<int>::value << std::endl;std::cout << std::is_integral<char>::value << std::endl;std::cout << std::is_integral<float>::value << std::endl;std::cout << "========is_floating_point=======" << std::endl;std::cout << std::is_floating_point<float>::value << std::endl;std::cout << std::is_floating_point<int>::value << std::endl;std::cout << std::is_floating_point<double>::value << std::endl;std::cout << "========is_pointer=======" << std::endl;std::cout << std::is_pointer<float*>::value << std::endl;std::cout << std::is_pointer<int*>::value << std::endl;std::cout << "========is_lvalue_reference=======" << std::endl;std::cout << std::is_lvalue_reference<int&>::value << std::endl;std::cout << std::is_lvalue_reference<float&>::value << std::endl;std::cout << "========is_rvalue_reference=======" << std::endl;std::cout << std::is_rvalue_reference<int&&>::value << std::endl;std::cout << std::is_rvalue_reference<float&&>::value << std::endl;std::cout << "========is_function=======" << std::endl;std::cout << std::is_function<int>::value << std::endl;std::cout << std::is_function<void()>::value << std::endl;std::cout << std::is_function<void(int,int)>::value << std::endl;std::cout << std::is_function<int(int,int)>::value << std::endl;std::cout << std::is_function<int(...)>::value << std::endl;std::cout << "========is_member_function_pointer=======" << std::endl;std::cout << std::is_member_function_pointer<int(TestClass::*)(int,int)>::value << std::endl;std::cout << "========is_member_object_pointer=======" << std::endl;std::cout << std::is_member_object_pointer<float(TestClass::*)>::value << std::endl;std::cout << "========is_array=======" << std::endl;std::cout << std::is_array<std::vector<int>>::value << std::endl;std::cout << std::is_array<int[]>::value << std::endl;std::cout << "========is_arithmetic=======" << std::endl;std::cout << std::is_arithmetic<int>::value << std::endl;std::cout << std::is_arithmetic<float>::value << std::endl;std::cout << "========is_abstract=======" << std::endl;std::cout << std::is_abstract<FInterface>::value << std::endl;std::cout << std::is_abstract<ChilClass>::value << std::endl;system("pause");return 0;
}

测试结果:
在这里插入图片描述

二、is_same比较的一些案例

根据前面的知识我们可以知道,这样是不相同的
那么如何转换成相同类型呢

	std::cout << std::is_same<int&, int>::value << std::endl;

1.add_lvalue_reference,add_rvalue_reference

	std::cout << std::is_same<int&, std::add_lvalue_reference<int>::type>::value << std::endl;std::cout << std::is_same<int&&, std::add_rvalue_reference<int>::type>::value << std::endl;

2.remove_const,add_const

	std::cout << std::is_same<int, std::remove_const<const int>::type>::value << std::endl;std::cout << std::is_same<const int, std::add_const<int>::type>::value << std::endl;

三、conditional

有点类似三目运算符

	std::conditional<true, int, float>::type type1 = 10;std::conditional<false, int, float>::type type2 = 10;std::cout << typeid(type1).name() << std::endl;std::cout << typeid(type2).name() << std::endl;

可以看到运行后的结果
在这里插入图片描述
也可以加bool判断的表达式
如下:

	std::conditional<(2 < 3), int, float>::type type;

那么是如何实现的呢?
答案就是模板的匹配,true匹配一个模板,false匹配另外一个模板

可以看到下图的源码,定义了一个泛型模板,一个特化模板,由于优先匹配特化模板若没有匹配再去找泛化模板的顺序,故实现了此功能!
在这里插入图片描述

四、decay

decay 是用于去除修饰符的
可以看到如下代码,去除前后的变化

	std::decay<int&>::type A1;//intstd::decay<int&&>::type A2;//intstd::decay<const int>::type A3;//intstd::decay<int[100]>::type A4;//int*std::decay<int(int)>::type A5;//int(*)(int)

五、enable_if

比如我们只想根据传入函数参数的类型来进行限定可以使用enable_if

1.简单使用:

struct MyStruct
{};template<class T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type Func(T t)
{std::cout << "Run1" << std::endl;return t;
}template<class T>
typename std::enable_if<!std::is_arithmetic<T>::value, T>::type Func(T t)
{std::cout << "Run2" << std::endl;return t;
}

使用:
这样可以限定传入参数的类型,根据不同类型的参数做不同的操作

	MyStruct myStruct;int value1 = Func(1);float value2 = Func(1.2f);Func(myStruct);

2.举一反三:

template<class T>
void Func1(typename std::enable_if<std::is_arithmetic<T>::value, T>::type t)
{std::cout << "Run3" << std::endl;
}template<class T>
void Func1(typename std::enable_if<!std::is_arithmetic<T>::value, T>::type t)
{std::cout << "Run4" << std::endl;
}
	Func1<int>(2);Func1<float>(2.3f);Func1<MyStruct>(myStruct);
http://www.dtcms.com/a/277336.html

相关文章:

  • RedisJSON 技术揭秘`JSON.ARRTRIM`用窗口裁剪,让数组保持“刚刚好”
  • 5G NR PDCCH之处理流程
  • [Nagios Core] CGI接口 | 状态数据管理.dat | 性能优化
  • k8s存储入门
  • RabbitMQ 之仲裁队列
  • Matplotlib 中 plt.pcolormesh 函数的使用详解
  • 【sql学习之拉链表】
  • 【LLM-Agent】Qwen-Agent智能体框架使用
  • trySend、Channel 和 Flow 的工作原理
  • 【CMake】CMake创建、安装、使用静态库和动态库
  • 操作系统-第四章存储器管理和第五章设备管理-知识点整理(知识点学习 / 期末复习 / 面试 / 笔试)
  • 【hivesql 已知维度父子关系加工层级表】
  • C++每日刷题day2025.7.13
  • 什么是RAG(Retrieval-Augmented Generation)?一文读懂检索增强生成
  • RabbitMQ面试精讲 Day 2:RabbitMQ工作模型与消息流转
  • 12.I/O复用
  • 前端性能与可靠性工程:资源优化 - 加载性能的“低垂果实”
  • 从零开始学习深度学习-水果分类之PyQt5App
  • SpringBoot集成Redis、SpringCache
  • C++ 强制类型转换
  • 【操作系统】strace 跟踪系统调用(一)
  • (LeetCode 每日一题) 2410. 运动员和训练师的最大匹配数(排序、双指针)
  • es里为什么node和shard不是一对一的关系
  • Augment AI 0.502.0版本深度解析:Task、Guidelines、Memory三大核心功能实战指南
  • 将 NumPy 数组展平并转换为 Python 列表
  • 1.1.5 模块与包——AI教你学Django
  • OpenLayers 入门指南【二】:坐标系与投影转换
  • 把 DNA 当 PCIe:一条 365 nt 链实现 64 Gbps 片上光互连——基于链式 Förster 共振的分子级波分复用链路
  • 理解 Robots 协议:爬虫该遵守的“游戏规则”
  • MySQL逻辑删除与唯一索引冲突解决