//前向声明模板类template<typename T>class myfunction {};//单个类型参数模板完全特例化template<typename R, typename A1>class myfunction<R(A1)> {public:using PFUNC = R (*)(A1);public:myfunction(PFUNC pfunc) : _pfunc(pfunc) {}R operator()(A1 arg) {return _pfunc(arg);}private:PFUNC _pfunc;};
当function
对象接收hello
函数时,R
作为返回值会被推导为void
,A1
作为单一参数类型被推导为string
类型:
myfunction<void(string)> f1 = &hello;f1("hello world");//打印"hello world"
那现在如果我们要接收两个参数的sum
求和函数呢?
int sum(int a, int b) { return a + b; }
其实理解了function
的原理后,这个时候要接收一个双参数sum
求和函数,可以再去特化一个适合sum
的类,其中R
推导为int
,A1
为sum
的第一个参数类型int
,A2
为sum
的第二个类型int
:
#include <iostream>using namespace std;int sum(int a, int b) { return a + b; }template<typename T>class myfunction {};//两个类型参数模板完全特例化template<typename R, typename A1, typename A2>class myfunction<R(A1, A2)> {public:using PFUNC = R (*)(A1, A2);public:myfunction(PFUNC pfunc) : _pfunc(pfunc) {}R operator()(A1 arg1, A2 arg2) {return _pfunc(arg1, arg2);}private:PFUNC _pfunc;};int main() {myfunction<int(int, int)> f2 = ∑// myfunction<int(int, int)> f2(&sum);cout << f2(3, 4) << endl;// 输出5return 0;}
以上就是function
去接收单参数和双参数时的实现,但是这有个很致命的缺点,如果要接收三个参数、四个参数、十个参数、一百个参数、一千个参数呢?(当然这不太可能,就是单纯去考虑这种情况),那是不是还得对不同参数都进行一次实现?那模板的意义何在?如何消除代码冗余就是问题所在,我们需要用到可变模板参数,我的这篇文章已经说明什么是可变参数模板,如何去使用它:[ 泛化之美 —— C++11 可变参数模板的妙用 ]
所以通过可变模板参数,我们去实现一个可变参数的function
,该function
可以接收任意数量参数的函数、函数对象、lambda
表达式、bind
适配后的成员函数和普通函数等等:
template<typename T>class myfunction {};/*那如果类型参数多了,我们还要一个一个定义吗??其实可以采用变长参数模板实现*/// 可变参数模板完全特例化template<typename R, typename... A>class myfunction<R(A...)> {public:using PFUNC = R (*)(A...);public:myfunction(PFUNC pfunc) : _pfunc(pfunc) {}R operator()(A... arg) {return _pfunc(arg...);}private:PFUNC _pfunc;};
根据以上实现,我们对function
的底层原理有了深刻的认识,能够自己实现一个接收任意参数的function
模板类 。虽然以上实现和标准库还差得很远,但是起到了学习、理解的作用吧 。
总结本文通过C++11之前的bind1st
和bind2nd
引入,介绍了C++11的bind的使用,理清了它的作用,何谓“绑定”?然后介绍了function
的使用方法,并对其进行了逻辑上的实现,以上这些知识点都挺难的,涉及函数对象、模板特化、可变参数模板 。但是也算是一次系统性总结吧,感觉意义蛮大的 。C++11的路还很远,以后有机会再继续深耕吧 。
顺便记录一下,我还在为自己的秋招迷茫中,如果有好消息,我在回来还愿!
【C++11绑定器bind及function机制】
经验总结扩展阅读
- 路由器每天晚上都关掉好不好路由器每天晚上都关掉会怎么样
- 路由器放在墙边还是角落 路由器放在哪里比较好
- 路由器辐射是手机的多少倍 路由器辐射怎么减少
- 2023年9月22日是安机器的黄道吉日吗 2023年农历八月初八宜安机器吗
- 2023年9月22日适合安装机器吗 2023年9月22日安装机器好吗
- 2023年9月23日是安机器吉日吗 2023年农历八月初九安机器吉日
- 2023年9月23日是安装机器吉日吗 2023年9月23日安装机器行吗
- .net core Blazor+自定义日志提供器实现实时日志查看器
- 干粉灭火器如何使用
- c类火灾用什么灭火器