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

做网站空间 阿里云免费生成短链接

做网站空间 阿里云,免费生成短链接,做网站的内容样本,wordpress安装编辑器前言 在《std::function从实践到原理》中我们分析了std::function的实现原理,但这只是纸上谈兵。要想理解为什么这么实现,最好的办法还是想想要是自己手写一个要怎么实现。本文不想直接呈现最终版本,因为那样读者看不到某段代码是为了什么才…

前言

在《std::function从实践到原理》中我们分析了std::function的实现原理,但这只是纸上谈兵。要想理解为什么这么实现,最好的办法还是想想要是自己手写一个要怎么实现。本文不想直接呈现最终版本,因为那样读者看不到某段代码是为了什么才那么写。我会搭建好几版,争取把所想所思都体现出来。

第一版

我们先不考虑复制构造函数,也不考虑移动构造函数,只考虑最普通的构造函数, 一共两种类型可以赋值给Myfunction: lambda表达式、函数指针。这两种类型要么通过类模板参数要么通过构造函数的模板参数传进来,分别形如:

template<typename _Res, typename... _ArgTypes, typename _Functor>
class Myfunction 
//构造函数        
template<typename _Functor> 
Myfunction(_Functor __f){。。。
}

第一种要求用户必须这样使用:Myfunction<..., lambda0>, 但实际用户是给不出lambda表达式对应的类的(由编译器给出)。所以只能是第二种。然后还有个需求:用户传过来的lambda对象或者函数指针得copy一份,这样以后才能调用到它们(重载函数operator ()()中调用)所以这个Myfunction大概得长这样:

template<typename _Res, typename... _ArgTypes>
class Myfunction 
{
public:template<typename _Functor> Myfunction(_Functor __f){f = new _Functor(std::move(__f));}_Res operator()(_ArgTypes... __args) const{return (*f)(std::forward<_ArgTypes>(__args)...);}private:_Functor* f;
};

但这样有个大问题:_Functor作用域只在构造函数内,_Functor* f是编译不过的。所以f要承接lambda对象,也要承接函数指针,那只能是万能指针void* f或char* f了。

如果f成了void*类型,operator()()中还是得知道f原本的类型,不然没法编译通过。void* f不是callable的。_Functor只在构造函数中有,但operator()()却要使用,怎么办?

第二版

要解决这个问题,我们就得学一学std::function了。引入一个函数指针,它里面保留_Functor这个信息。

template<typename _Res, typename _Functor, typename... _ArgTypes>
class _MyFunction_handler
{
public:statc _Res _Function_handler_invoke(void* _Any_data,  _ArgTypes... __args){return (*(_Functor*)_Any_data)(std::forward<_ArgTypes>(__args)...);}
};template<typename _Res, typename... _ArgTypes>
class MyFunction;template<typename _Res, typename... _ArgTypes>
class MyFunction<_Res(_ArgTypes...)>
{
public:template<typename _Functor>MyFunction(_Functor __f){f = new _Functor(std::move(__f));_M_invoker = &_MyFunction_handler<_Res,_Functor,_ArgTypes...>::_Function_handler_invoke;}_Res operator()(_ArgTypes... __args) const{return (*_M_invoker)(f, std::forward<_ArgTypes>(__args)...);}private:void* f;typedef _Res (*_Invoker_type)(void* _Any_data, _ArgTypes...);_Invoker_type _M_invoker;
};

_M_invoker是一个桥梁,把构造和调用连接了起来(_Functor方面) 。写几个测试用例试一试:

int gAdd(int a, int b){return a+b;
}int main(){MyFunction<int(int,int)> f1 = [](int a,int b)->int {return a+b;};int res = f1(1,2);std::cout<<res<<std::endl;MyFunction<int(int,int)> f2 = gAdd;int res2 = f2(3,4);std::cout<<res2<<std::endl;
}

能走通了!

显然有个问题:new的东西没释放。依照_M_invoker再搞一个_M_destroy。

第三版

#include <iostream>template<typename _Res, typename _Functor, typename... _ArgTypes>
class _MyFunction_handler
{
public:statc _Res _Function_handler_invoke(void* _Any_data,  _ArgTypes... __args){return (*(_Functor*)_Any_data)(std::forward<_ArgTypes>(__args)...);}static void _Function_handler_destroy(void* _Any_data){//((_Functor*)_Any_data)->~_Functor();delete ((_Functor*)_Any_data);_Any_data = nullptr;}
};template<typename _Res, typename... _ArgTypes>
class MyFunction;template<typename _Res, typename... _ArgTypes>
class MyFunction<_Res(_ArgTypes...)>
{
public:template<typename _Functor>MyFunction(_Functor __f){f = new _Functor(std::move(__f));_M_invoker = &_MyFunction_handler<_Res,_Functor,_ArgTypes...>::_Function_handler_invoke;_M_destroy = &_MyFunction_handler<_Res,_Functor,_ArgTypes...>::_Function_handler_destroy;}_Res operator()(_ArgTypes... __args) const{return (*_M_invoker)(f, std::forward<_ArgTypes>(__args)...);}~MyFunction(){(*_M_destroy)(f);}
private:void* f;typedef _Res (*_Invoker_type)(void* _Any_data, _ArgTypes...);_Invoker_type _M_invoker;typedef void (*_Destroy_type)(void* _Any_data);_Destroy_type _M_destroy;};int gAdd(int a, int b){return a+b;
}int main(){MyFunction<int(int,int)> f1 = [](int a,int b)->int {return a+b;};int res = f1(1,2);std::cout<<res<<std::endl;MyFunction<int(int,int)> f2 = gAdd;int res2 = f2(3,4);std::cout<<res2<<std::endl;}

[mzhai@~]$ g++ myfunction.cpp -std=c++11 -g
[mzhai@~]$ ./a.out
3
7
[mzhai@c++11]$ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt1 ./a.out
3
7

valgrind测试也没有内存泄漏。

完美?NO,还没有处理给Myfunction赋值nullptr的情况。 还没有写各种各样的构造函数。路已经走通了,这些都是修修补补,不再赘述。

http://www.hkea.cn/news/342437/

相关文章:

  • 购物网站开发文献综述百度收录需要多久
  • 营销型企业网站建设案例设计公司网站
  • 国际外贸网站电子商务
  • 南充做网站 www.xinbay.com全国免费发布广告信息
  • 备案 个人网站软件开发培训中心
  • 江苏网站建设网络推广关键词批量调词 软件
  • 东莞企业网站建设价格怎么在百度发布免费广告
  • 网站后台地址一般是在线seo优化工具
  • 海曙区住房和建设局网站备案域名
  • 网站建设硬件环境志鸿优化设计答案
  • 网页游戏网址推荐宁波网站推广网站优化
  • 福建就福建省住房与城乡建设厅网站高端网站建设企业
  • 网站如何做seo规划app怎么开发出来的
  • 吴江住房和城乡建设局官方网站产品软文是什么
  • 公司网站制作设谷歌seo是什么职业
  • 北京品牌高端网站建设公司燕郊今日头条
  • 网站制作公司徐州宁波网站seo哪家好
  • 做网站基本费用大概需要多少全媒体运营师报考官网在哪里
  • 网站建设款属于什么科目营业推广策划
  • 建设网站查证书网络广告有哪些形式
  • 分布式网站开发网络销售平台排名
  • 网站建设模板购买品牌seo培训
  • 深圳网站建设 cms网站推广交换链接
  • 标准物质网站建设5118站长工具箱
  • 做一个能注册用户的网站网络推广费用大概价格
  • 网站建设评价东莞谷歌推广
  • php网站后台进不去百度推广入口官网
  • 个人网站一键生成免费推广网站有哪些
  • 厦门做网站设计电商seo优化
  • wordpress视频点播seo技术是干什么的