C++组件扩展实现:函数特性function_traits

news/2024/11/24 9:36:07/
#include<functional>
#include<tuple>
#include<type_traits>
#include<iostream>
using namespace std;template<typename T>
struct function_traits;//处理普通函数
template<typename RET,typename ...ARGS>
struct function_traits<RET(ARGS...)>
{constexpr static size_t arity = sizeof...(ARGS);using function_type = RET(ARGS...);using Ret_type = RET;using stl_functional_type = std::function<function_type>;using function_pointer = RET(*)(ARGS...);template<size_t I>struct ArgN{static_assert(I < arity, "failed!");using type = std::tuple_element_t<I, std::tuple<ARGS...>>;};template<size_t I>using ArgN_t = typename ArgN<I>::type;
};//处理函数指针
template<typename RET, typename ...ARGS>
struct function_traits<RET(*)(ARGS...)> :function_traits<RET(ARGS...)> {using function_type = RET(*)(ARGS...);
};
//处理std::function
template<typename RET, typename ...ARGS>
struct function_traits<std::function<RET(ARGS...)>> :function_traits<RET(ARGS...)> {using function_type = std::function<RET(ARGS...)>;
};/*
【使用可变参数宏实现,可变参数宏的列表...与宏定义中的__VA_ARGS__ 对应替换;而非与宏定义中的...对应替换】可变参数为空:
假如定义了如下宏(不管是使用标准 C 方式还是 GNU C方式都可以,这里使用标准 C 的方式):
#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)
在标准 C 的环境下进行如下调用,可变参数为空:
eprintf("success!\n");
宏的扩展将会报错,因为扩展出来后的形式如下:fprintf(stderr, "success!\n",);
fprintf 最后一个参数后面多了一个逗号,这样将报错。这种情况在标准 C 下无法解决,但是 GNU C可以解决。GNU C 赋予 "##" 另一种特殊意义(不是字符串连接的意义了),如果在可变参数前面加上"##",当可变参数为空时,前面的逗号会被删除:#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
// 或者
#define eprintf(format, args...) fprintf(stderr, format, ##args)
当可变参数为空时,宏都会扩展成:
fprintf(stderr, "success!\n");
可以看到最后一个参数后面的逗号被删除了。
Clang 默认使用 GNU11,因此也支持这个功能。
*///处理成员函数
#define FUNCTION_TRAITS(...)															    \
template<typename RET, typename Class,typename ...ARGS>										\
struct function_traits<RET(Class::*)(ARGS...)__VA_ARGS__> :function_traits<RET(ARGS...)> {	\using function_type = RET(Class::*)(ARGS...)__VA_ARGS__;								\
protected:																					\using logic_function_type= RET(ARGS...);									            \
};FUNCTION_TRAITS()
FUNCTION_TRAITS(const)
FUNCTION_TRAITS(volatile)
FUNCTION_TRAITS(const volatile)//处理函数对象
template<typename Callable>
struct function_traits :function_traits<decltype(&Callable::operator())> {using function_type =typename function_traits<Callable>::logic_function_type;//函数对象模拟成普通函数的类型
};template<typename T>
void Print_Type()
{std::cout << typeid(T).name() << std::endl;
}int Print(int, double) { return 0; }//函数对象
struct MyStruct
{double Fn(char, char) const { return 0; }char operator()(double, char*) {return ' ';}
};int main()
{auto fn = std::function<int(int, double)>(Print);Print_Type<function_traits<decltype(fn)>::function_type>();constexpr auto nargs = function_traits<decltype(Print)>::arity;Print_Type<function_traits<decltype(Print)>::function_type>();Print_Type<function_traits<decltype(&Print)>::function_type>();Print_Type<function_traits<MyStruct>::function_type>();Print_Type<function_traits<decltype(&MyStruct::Fn)>::function_type>();using T = decltype(&MyStruct::Fn);Print_Type<T>();Print_Type<function_traits<decltype(Print)>::Ret_type>();Print_Type<function_traits<decltype(Print)>::function_pointer>();Print_Type<function_traits<decltype(Print)>::ArgN_t<1>>();return 0;
}

http://www.ppmy.cn/news/629151.html

相关文章

FFmpeg音视频开发知识点(二)

系列文章目录 FFmpeg音视频开发知识点&#xff08;一&#xff09; 文章目录 系列文章目录前言一、AAC音频编码1. ffmpeg编译第三方的libfdk_aac2. S16重采样FLTP 二、AAC音频解码总结 前言 该篇讲解一下&#xff0c;音频编解码中的难点&#xff0c;以及开发过程中遇到问题&am…

计算机硬件配置一般看什么CPU,电脑配置怎么看好坏

电脑配置怎么看好坏 电脑有硬件和软件组成,而决定电脑性能有四大部件,分别为CPU、显卡、内存、硬盘。任何一个的性能弱,都会造成电脑慢。那么电脑配置怎么看好坏?下面一起来看看。 一、处理器cpu看什么 处理器是电脑控制的核心,一套搭配合理电脑,看处理器可以看出整机的档…

计算机系统处理器好坏怎么看,新手装机教程:怎么看cpu好坏?电脑cpu参数怎么看?...

「辰鸿科普」 电脑cpu参数怎么看&#xff1f;cpu对于一台电脑的重要性就好比汽车里的发动机&#xff0c;然而很多用户在选择cpu的时候不知道怎么看cpu好坏&#xff0c;稍微懂那么一点点的还知道个酷睿、奔腾&#xff0c;或者双核&#xff0c;四核之类的。然而仅仅知道这些是不够…

计算机配置好坏怎么看,怎么看电脑配置好坏

怎么看电脑配置好坏 很多人都只懂得使用电脑却不懂怎么看电脑配置好坏&#xff0c;这对电脑的维护和使用都不利的&#xff0c;下面就来分享一下怎么看电脑配置好坏。 步骤1、右键“我的电脑”&#xff0c;常规里有简单电脑配置&#xff0c;具体一点的在“硬件”&#xff0c;打开…

如何区分显卡的好坏?

1. 分A卡和N卡&#xff0c;A卡就是ATI&#xff0c;N卡呢就是NVIDIA&#xff0c;首先是厂商这些分一线场和二线厂&#xff0c;A卡首选蓝宝石出的&#xff0c;N卡首选影驰出的~型号之分呢举个例子吧&#xff0c;拿N卡来说&#xff0c;7300和7600虽说只差一个型号&#xff0c;但价…

logcat

文章目录 定义日志记录抓取日志优先级输出格式 定义 logcat是一个命令行工具&#xff0c;用于转储系统消息日志&#xff0c;包括设备抛出错误时的堆栈轨迹&#xff0c;以及从所有应用中使用 Log 类写入的消息 日志记录 系统进程logd维护的一组结构化环形缓冲区&#xff0c;缓…

Unable to Locate package python2 | Linux Ubuntu系统下python2和cif2cell的安装

Linux Ubuntu系统下python2的安装 安装键入命令和报错如下&#xff1a; 背景&#xff1a;官方早年前已经宣布停止 Python 2 的更新和服务&#xff0c;所以对于ubuntu20版本之后的&#xff0c;都是自带安装了python3&#xff0c;但是我们在处理安装某些大型科学计算程序的时候…

科幻-奇幻小说TOP100

1.《魔戒之王》&#xff08;奇幻&#xff09;--J.R.R.托尔金 所有奇幻文学的鼻祖&#xff0c;当然&#xff0c;赢得了我们最顶端的位置。除了全然独立创造了奇幻文学类型和影响了几代作家之外&#xff0c;托肯恩的传说讲述了一个宏大的故事。 The Lord of the Rings. J.R.R. …