C++代码片段(一)萃取函数返回值类型,参数类型,参数个数
函数的类型主要集中在以下几种
- 函数指针
- 函数对象,是一个类对象,内部重载的operator()函数是一个函数指针
- lambda,匿名函数对象,同函数对象
- function对象
后三者都是类对象,可以看成一种类型
定义基础模板类
template <typename T>
struct function_traits;
针对函数指针进行偏特化
对于函数指针,存在两种情况
- 直接通过decltype获取类型
- 利用模板推导类型
int pointer_func(int a, int b) {return a + b;
}
// decltype(pointer_func) is int(int, int)
int pointer_func(int a, int b) {return a + b;
}
template <typename Func>
void traits_test1(Func&&) {}
template <typename Func>
void traits_test2(Func) {}
int main() {// Func = int(&)(int, int)traits_test1(pointer_func);// Func = int(*)(int, int)traits_test2(pointer_func);
}
不难发现,函数指针的类型为
- R(*)(Args…)
- R(&)(Args…)
- R(Args…)
其中R是函数返回值类型,Args是函数的参数列表,针对这三种进行特化
template <typename R, typename... Args>
struct function_traits_helper
{static constexpr auto param_count = sizeof...(Args);using return_type = R;template <std::size_t N>using param_type = std::tuple_element_t<N, std::tuple<Args...>>;
};// int(*)(int, int)
template <typename R, typename... Args>
struct function_traits<R(*)(Args...)> : public function_traits_helper<R, Args...>
{
};// int(&)(int, int)
template <typename R, typename... Args>
struct function_traits<R(&)(Args...)> : public function_traits_helper<R, Args...>
{
};// int(int, int)
template <typename R, typename... Args>
struct function_traits<R(Args...)> : public function_traits_helper<R, Args...>
{
};
针对lambda进行偏特化
假设在main函数中定义一个匿名函数lambda,通过模板参数类型推导判断它的类型
template <typename Func>
void traits_test(Func&&) {}int main()
{auto f = [](int a, int b) { return a + b; };// Func = main()::<lambda(int, int)> const// Func::operator() = int(main()::<lambda(int, int)>*)(int, int) consttraits_test(f);return 0;
}
lambda实际上是一个匿名函数对象,可以理解为内部也重载了operator()函数,所以如果将lambda整体进行推导,那么会推导出一个main()::
template <typename R, typename... Args>
struct function_traits_helper
{static constexpr auto param_count = sizeof...(Args);using return_type = R;template <std::size_t N>using param_type = std::tuple_element_t<N, std::tuple<Args...>>;
};template <typename ClassType, typename R, typename... Args>
struct function_traits<R(ClassType::*)(Args...) const> : public function_traits_helper<R, Args...>
{using class_type = ClassType;
};template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
通过std::function和std::bind绑定的函数对象和lambda类型相同,不需要额外的特化
增加const版本
针对某些可能推导出const的增加const版本,比如上述的lambda
完整代码请参考这里
C++代码片段(一)萃取函数返回值类型,参数类型,参数个数相关推荐
- 【C 语言】C 项目开发代码规范 ( 形参合法性判断 | 函数返回值局部变量 | 函数中不用全局变量 | 函数中使用局部变量接收形参 | 函数返回值 | 形参作返回值 | 形参返回值处理 )
文章目录 一.C 项目开发代码规范 一.C 项目开发代码规范 上一篇博客 [C 语言]字符串模型 ( 键值对模型 ) 中 , 完成了字符串的 键值对 查找功能 , 代码不太规范 ; C 项目开发代码规 ...
- 函数返回值为指针类型的总结
参考博客:https://blog.csdn.net/zxccaoya/article/details/53468500 char*GetString(void) {char p[]= "h ...
- typescript 数据类型、函数返回值、类型断言、联合类型、类型兼容
null和undefined类型:是所有类型的子类型,即可以将任意类型赋值为二者any类型:可以赋值任何类型unknown类型:引入的顶级类型unknown,对照于any,unknown是类型安全的, ...
- c语言函数返回值可以是字符串吗,函数返回值可以是字符串吗
c语言中函数返回值可以是数组.字符串和结构体吗? 因为在C语言中函数不能返回数组,但字符串是存储在字符数组中的,所以能C语言中实现函数返回字符串,首先要确定函数返回的字符串地址的来源,一般分为四种方式 ...
- 2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码)
2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码) 1.引用(普通引用) 变量 ...
- C语言100题第二题 编写函数fun()的功能并调用:从3个红球,5个白球,6个黑球中任意取8个 作为一组,进行输出。在每组中,可以没有黑球,但是必须有红球和白球。组合数作为函数返回值。
结构:分析-代码-总结 原题 分析 代码 总结 原题 编写函数fun()的功能并调用:从3个红球,5个白球,6个黑球中任意取8个 作为一组,进行输出.在每组中,可以没有黑球,但是必须有红球和白球.组合 ...
- python返回值return用法_Python中return函数返回值代码实例用法
本篇文章小编给大家分享一下Python中return函数返回值代码实例用法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. return 添加返回值 r ...
- python函数的用法详解(作用、定义、调用、函数参数、函数返回值、函数说明文档、函数嵌套使用)
1. 函数的作⽤ 函数就是将⼀段具有独⽴功能的代码块整合到⼀个整体并命名,在需要的位置调⽤这个名称即可完成对应的需求. 函数在开发过程中,可以更⾼效的实现代码重⽤. 2. 函数的使⽤步骤 2.1 定义 ...
- go函数详解:函数定义、形参、返回值定义规范、函数内存分析、不支持重载、支持可变参数、基本数据类型和数组默认都是值传递的、支持自定义数据类型、函数返回值命名
引入 [1]为什么要使用函数: 提高代码的复用型,减少代码的冗余,代码的维护性也提高了 [2]函数的定义: 为完成某一功能的程序指令(语句)的集合,称为函数. [3]基本语法 func 函数名(形参列 ...
最新文章
- MindSpore基准性能
- spring in action 4 线路图
- java common http_httpClient和common-httpclient的区别
- UVA 10746 Crime Wave - The Sequel
- stateful openflow------整理openstate原理以及具体应用
- iOS 9音频应用播放音频之ios9音频基本功能
- java 单链表约瑟夫环_java循环单链表实现约瑟夫环问题
- Ajax框架DWR入门
- [推荐]大量 Blazor 学习资源(二)
- 分布式 知乎 github_如何使用GitHub本机功能来帮助管理中型分布式团队
- CNN中全连接层是什么样的
- Java 设计模式之中介者模式
- 手机可以和linux数据互传吗,没网络也可以传输数据?OPPO互传与HUAWEI Share实测体验...
- 没有人更比他懂基金业务:博格和他的先锋集团创业史(4):
- OpenCV2:Mat属性type,depth,step
- GAN的目标函数(F散度;KL散度;JS散度;Pearson \chi^2 散度;IPM;Wasserstein距离;MMD)
- 你在用FastReport.Net报表工具做报表没
- pythonlambda多行_Python中通过lambda抛异常的奇迹淫巧
- APK文件的安装方法
- 全国哀悼日 网站变灰装(附代码)