<五>function的实现原理
类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。
通常std::function是一个函数对象类,它包装其它任意的函数对象,被包装的函数对象具有类型为T1, …,TN的N个参数,并且返回一个可转换到R类型的值。std::function使用 模板转换构造函数接收被包装的函数对象;特别是,闭包类型可以隐式地转换为std::function
自己实现function
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class MyFunction3 {
};
template<typename Ty, typename A1>
class MyFunction3<Ty(A1)> {
public:
typedef Ty(*pFunction)(A1);//定义一个函数指针,指针指向的函数返回类型是Ty,有1个函数参数
MyFunction3<Ty(A1)>(pFunction _pFunction) : _function(_pFunction) {
}
Ty operator()(A1 arg1) {
return (*_function)(arg1);
}
private:
pFunction _function;
};
template<typename Ty,typename A1,typename A2>
class MyFunction3<Ty(A1,A2)> {
public:
typedef Ty(*pFunction)(A1, A2);//定义一个函数指针,指针指向的函数返回类型是Ty,有两个函数参数
MyFunction3<Ty(A1, A2)>(pFunction _pFunction):_function(_pFunction) {
}
Ty operator()(A1 arg1, A2 arg2) {
return (*_function)(arg1, arg2);
}
private:
pFunction _function;
};
void showMes(string mes) {
cout << "showMes(string mes)=" << mes << endl;
}
int sum1(int x, int y) {
cout << "sum1 "<<(x+y) << endl;
return x + y;
}
int sum2(int x, int y) {
cout << "sum2 " << (x + y) << endl;
return x + y;
}
int main() {
MyFunction3<int(int, int)> f1(sum1);
f1(20,30);
MyFunction3<void(string)> f2(showMes);
f2("AAAA");
system("pause");
return 0;
}
上面代码我们实现了两个模板的部分特例化
class MyFunction3<Ty(A1)> 一个函数参数的
class MyFunction3<Ty(A1,A2)> 两个函数参数的
所以问题来了...三个参数,四个参数,五个参数等若干个参数的怎么办?
可以使用C++11 可变参数类型, 具体如下
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class MyFunction4 {
};
template<typename R , typename... A >
class MyFunction4<R(A...)> {
public:
typedef R(*PFUNCTION)(A...);
MyFunction4<R(A...)>(PFUNCTION _p) : function(_p) {}
R operator()(A... arg) {
return (*function)(arg...);
}
private:
PFUNCTION function;
};
void showMes1(string mes) {
cout << "showMes(string mes)=" << mes << endl;
}
int sum11(int x, int y) {
cout << "sum11 " << (x + y) << endl;
return x + y;
}
int sum21(int x, int y) {
cout << "sum21 " << (x + y) << endl;
return x + y;
}
int main() {
MyFunction4<int(int, int)> f1(sum11);
f1(20, 30);
MyFunction4<void(string)> f2(showMes1);
f2("AAAA");
system("pause");
return 0;
}
<五>function的实现原理的更多相关文章
- 2017-2018-2 《网络对抗技术》 20155322 第五周 Exp2 后门原理与实践
#2017-2018-2 <网络对抗技术> 20155322 第五周 Exp2 后门原理与实践 [博客目录] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过 ...
- [转帖]Docker五种存储驱动原理及应用场景和性能测试对比
Docker五种存储驱动原理及应用场景和性能测试对比 来源:http://dockone.io/article/1513 作者: 陈爱珍 布道师@七牛云 Docker最开始采用AUFS作为文件系统 ...
- MySQL 第五篇:索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- SQL学习笔记五之MySQL索引原理与慢查询优化
阅读目录 一 介绍 二 索引的原理 三 索引的数据结构 四 聚集索引与辅助索引 五 MySQL索引管理 六 测试索引 七 正确使用索引 八 联合索引与覆盖索引 九 查询优化神器-explain 十 慢 ...
- 集合总结五(Hashtable的实现原理)
一.概述 上一篇介绍了Java8的HashMap,接下来准备介绍一下Hashtable. Hashtable可以说已经具有一定的历史了,现在也很少使用到Hashtable了,更多的是使用HashMap ...
- ASP.NET MVC学习(五)之MVC原理解析
ASP.NET MVC 请求生命周期 生命周期步骤概览 当我们对ASP.NET MVC网站发出一个请求的时候,会发生5个主要步骤: 步骤1:创建RouteTable 当ASP.NET应用程序第一次启动 ...
- JavaScript学习总结(十五)——Function类
在JavaScript中,函数其实是对象,每个函数都是Function类的实例,既然函数对象,那么就具有自己的属性和方法,因此,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. 一.函数的 ...
- swift语言点评五-Function
一.函数类型 Every function in Swift has a type, consisting of the function’s parameter types and return t ...
- Salesforce学习之路-developer篇(五)Aura组件原理及常用属性
很喜欢曾经看到的一句话:以输出倒逼输入.以输出的形式强制自己学习,确实是高效的学习方式,真的很棒.以下仅为个人学习理解,如有错误,欢迎指出,共同学习. 1. 什么是Lightning Componen ...
- Libcurl笔记五_easy模式运行原理
1, curl_easy_init内部调用Curl_open创建一个结构体SessionHandle(里面包含了所以curl使用的数据和指针)并初始化一些数据,然后返回将其作为给外侧使用的句柄CURL ...
随机推荐
- windows系统下使用bat脚本文件设置 tomcat 系统环境变量
说明:在一个bat文件中设置tomcat环境变量后,不能直接使用,需要另起一个bat文件才能使用 号开头的行不要写在bat文件中 # tomcat1.bat # 这个bat文件实现的功能:设置环境变量 ...
- Docker 部署 JIRA(破解版)
一. 说明 1.1 素材 本文采用素材如下: Docker镜像 Github链接(https://github.com/cptactionhank) 破解工具 Gitee链接(https://gite ...
- .Net CLR GC plan_phase二叉树和Brick_table
楔子 别那么懒,勤快点.以下取自CLR PreView 7.0. 主题 GC计划阶段(plan_phase)主要就两个部分,一个是堆里面的对象构建一颗二叉树(这颗二叉树的每个节点包含了诸如对象移动信息 ...
- 基于tauri打造的HTTP API客户端工具-CyberAPI
国庆长假和朋友聚会的时候,和朋友谈起最近这段时间捣鼓tauri,写了一个HTTP API客户端工具.『你写了这么多东西,其实有想过是为了啥不?』为了啥这是一个很大的命题,当初每个项目的时候都想过它应该 ...
- surging 将推出社区版微服务平台
前言 对于.NET大家并不陌生,有大批的企业选择.NET作为公司构建多种应用的开发平台,但是近几年随着微服务,大数据,移动端,物联网兴起,而后.NET社区生态没有跟上时代的步伐,已开始趋于没落,而其中 ...
- 沁恒CH32V003F4P6 开发板上手报告和Win10环境配置
CH32V003 沁恒最近推出的低价CH32V003系列, 基于青稞RISC-V2A内核, 48MHz主频, 2KB SRAM, 16KB Flash, 工作电压兼容3.3V和5V. 主要参数如下 S ...
- ATT&CK框架整理(中英文整理)
工作需要了解了一下ATT&CK框架,留个记录.
- 精简docker的导出镜像
Docker 镜像是由多个文件系统(只读层)叠加而成,每个层仅包含了前一层的差异部分.当我们启动一个容器的时候,Docker 会加载镜像层并在其上添加一个可写层.容器上所做的任何更改,譬如新建文件.更 ...
- docker容器化业务
1.环境准备: 设备 IP地址 作用 系统版本 mysql-master 192.168.100.213 Nginx-Web服务器 Ubuntu2004 mysql-slave 192.168.100 ...
- 利用xtrabackup8完全,增量备份及还原MySQL8
利用xtrabackup8完全,增量备份及还原MySQL8 1.环境准备 服务器 作用 数据库版本 xtrabackup版本 10.0.0.8 数据备份 mysql8.0.26 8.0.28 10.0 ...