在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++ function技術(shù)的實(shí)現(xiàn)與具體運(yùn)用

Linux愛(ài)好者 ? 來(lái)源:xdesk ? 作者:xdesk ? 2021-01-20 09:23 ? 次閱讀

【導(dǎo)讀】:本文主要講解C++ function技術(shù)的實(shí)現(xiàn)與具體運(yùn)用。

std::function是一個(gè)函數(shù)對(duì)象的包裝器,std::function的實(shí)例可以存儲(chǔ),復(fù)制和調(diào)用任何可調(diào)用的目標(biāo),包括:

函數(shù)。

lamada表達(dá)式。

綁定表達(dá)式或其他函數(shù)對(duì)象。

指向成員函數(shù)和指向數(shù)據(jù)成員的指針。

當(dāng)std::function對(duì)象沒(méi)有初始化任何實(shí)際的可調(diào)用元素,調(diào)用std::function對(duì)象將拋出std::bad_function_call異常。

本文我們來(lái)談一下std::function的實(shí)現(xiàn)原理。

1. std::function簡(jiǎn)介

在討論其原理的時(shí)候,我們來(lái)熟悉一下這個(gè)東西是怎么使用的,C++標(biāo)準(zhǔn)庫(kù)詳細(xì)說(shuō)明了這個(gè)的基本使用http://www.cplusplus.com/reference/functional/function/.

這里我們大概總結(jié)一下。

1.1 Member types

result_type 返回類型
argument_type 如果函數(shù)對(duì)象只有一個(gè)參數(shù),那么這個(gè)代表參數(shù)類型。
first_argument_type 如果函數(shù)對(duì)象有兩個(gè)個(gè)參數(shù),那么這個(gè)代表第一個(gè)參數(shù)類型。
second_argument_type 如果函數(shù)對(duì)象有兩個(gè)個(gè)參數(shù),那么這個(gè)代表第二個(gè)參數(shù)類型。
成員類型 說(shuō)明

1.2 Member functions

constructor 構(gòu)造函數(shù):constructs a new std::function instance
destructor 析構(gòu)函數(shù):destroys a std::function instance
operator= 給定義的function對(duì)象賦值
operator bool 檢查定義的function對(duì)象是否包含一個(gè)有效的對(duì)象
operator() 調(diào)用一個(gè)對(duì)象
成員函數(shù)聲明 說(shuō)明

1.3 基本使用

#include #include intfun(inta,intb,intc,intd) { std::cout<f; f=[](inta,intb,intc,intd)->int { std::cout<

從上面我們可以發(fā)現(xiàn),std::function可以表示函數(shù),lamada,可調(diào)用類對(duì)象。

2. std::function實(shí)現(xiàn)

在標(biāo)準(zhǔn)庫(kù)中STL設(shè)計(jì)為如下:

template struct_Arg_types {//provideargument_type,etc.(sometimes) }; template struct_Arg_types<_Ty1> {//provideargument_type,etc.(sometimes) typedef_Ty1argument_type; }; template struct_Arg_types<_Ty1,?_Ty2> {//provideargument_type,etc.(sometimes) typedef_Ty1first_argument_type; typedef_Ty2second_argument_type; }; template class_Func_class :public_Arg_types<_Types...> {//implementfunctiontemplate public: typedef_Retresult_type; typedef_Func_class<_Ret,?_Types...>_Myt; typedef_Func_base<_Ret,?_Types...>_Ptrt; private: bool_Local()const_NOEXCEPT {//testforlocallystoredcopyofobject return(_Getimpl()==_Getspace()); } union_Storage {//storageforsmallobjects(basic_stringissmall) max_align_t_Dummy1;//formaximumalignment char_Dummy2[_Space_size];//topermitaliasing _Ptrt*_Ptrs[_Num_ptrs];//_Ptrs[_Num_ptrs-1]isreserved }; _Storage_Mystorage; }; template struct_Get_function_impl<_Ret?CALL_OPT?(_Types...)> {/*determinetypefromargumentlist*/ typedef_Func_class<_Ret,?_Types...>type; }; template classfunction :public_Get_function_impl<_Fty>::type {//wrapperforcallableobjects public: typedeffunction<_Fty>_Myt; };

上面的std::function繼承關(guān)系比較簡(jiǎn)單,主要使用

union_Storage { //storageforsmallobjects(basic_stringissmall) max_align_t_Dummy1;//formaximumalignment char_Dummy2[_Space_size];//topermitaliasing _Ptrt*_Ptrs[_Num_ptrs];//_Ptrs[_Num_ptrs-1]isreserved };

這個(gè)來(lái)存儲(chǔ)我們?cè)O(shè)置的可調(diào)用對(duì)象,我們從std::function的使用過(guò)程看一下整個(gè)原理。

2.1 函數(shù)對(duì)象賦值

我們使用的時(shí)候一般使用f = Caller;來(lái)設(shè)置函數(shù)對(duì)象,我們看下這個(gè)的實(shí)現(xiàn)過(guò)程。

template _Myt&operator=(reference_wrapper<_Fx>_Func)_NOEXCEPT { //assignwrapperholdingreference_wrappertofunctionobject this->_Tidy(); this->_Reset(_Func); return(*this); }

我們看this->_Reset(_Func)這個(gè)函數(shù),因?yàn)檫@個(gè)才是設(shè)置函數(shù)可調(diào)用對(duì)象的東西。

void_Set(_Ptrt*_Ptr)_NOEXCEPT {//storepointertoobject _Mystorage._Ptrs[_Num_ptrs-1]=_Ptr; } void_Reset_impl(_Fx&&_Val,const_Alloc&_Ax, _Myimpl*,_Alimpl&_Al,false_type) {//storecopyof_Valwithallocator,small(locallystored) _Myimpl*_Ptr=static_cast<_Myimpl?*>(_Getspace()); _Al.construct(_Ptr,_STDforward<_Fx>(_Val),_Ax); _Set(_Ptr); } template void_Reset_alloc(_Fx&&_Val,const_Alloc&_Ax) {//storecopyof_Valwithallocator if(!_Test_callable(_Val)) {//nullmemberpointer/functionpointer/std::function return;//alreadyempty } typedeftypenamedecay<_Fx>::type_Decayed; typedef_Func_impl<_Decayed,?_Alloc,?_Ret,?_Types...>_Myimpl; _Myimpl*_Ptr=0; typedef_Wrap_alloc<_Alloc>_Alimpl0; typedeftypename_Alimpl0::templaterebind<_Myimpl>::other_Alimpl; _Alimpl_Al(_Ax); _Reset_impl(_STDforward<_Fx>(_Val),_Ax, _Ptr,_Al,_Is_large<_Myimpl>()); } template void_Reset(_Fx&&_Val) { //storecopyof_Val _Reset_alloc(_STDforward<_Fx>(_Val),allocator()); }

這個(gè)代碼的主要意思就是創(chuàng)建一個(gè)_Func_impl<_Decayed, _Alloc, _Ret, _Types...>指針,然后賦值_Mystorage._Ptrs[_Num_ptrs - 1] = _Ptr;。

設(shè)置之后,我們看下調(diào)用操作怎么完成。

2.2 operator() 的實(shí)現(xiàn)

調(diào)用操作主要是通過(guò)operator()來(lái)實(shí)現(xiàn)的,我們看下這個(gè)的實(shí)現(xiàn)過(guò)程。

_Ptrt*_Getimpl()const_NOEXCEPT {//getpointertoobject return(_Mystorage._Ptrs[_Num_ptrs-1]); } _Retoperator()(_Types..._Args)const {//callthroughstoredobject if(_Empty()) _Xbad_function_call(); return(_Getimpl()->_Do_call(_STDforward<_Types>(_Args)...)); }

因此,我們是通過(guò)_Func_impl<_Decayed, _Alloc, _Ret, _Types...>轉(zhuǎn)發(fā)了調(diào)用操作_Do_call

2.3 _Func_impl的實(shí)現(xiàn)

class_Func_impl :public_Func_base<_Rx,?_Types...> {//derivedclassforspecificimplementationtypes public: typedef_Func_impl<_Callable,?_Alloc,?_Rx,?_Types...>_Myt; typedef_Func_base<_Rx,?_Types...>_Mybase; typedef_Wrap_alloc<_Alloc>_Myalty0; typedeftypename_Myalty0::templaterebind<_Myt>::other_Myalty; typedefis_nothrow_move_constructible<_Callable>_Nothrow_move; virtual_Rx_Do_call(_Types&&..._Args) {//callwrappedfunction return(_Invoke_ret(_Forced<_Rx>(),_Callee(), _STDforward<_Types>(_Args)...)); } _Compressed_pair<_Alloc,?_Callable>_Mypair; };

_Func_impl這個(gè)類通過(guò)_Do_call來(lái)轉(zhuǎn)發(fā)函數(shù)對(duì)象的調(diào)用操作。

3. 總結(jié)

這里我們看下std::function的結(jié)構(gòu)信息,如下:

330d8784-5788-11eb-8b86-12bb97331649.png

從這里我們發(fā)現(xiàn)_Storage大小為:

constint_Num_ptrs=6+16/sizeof(void*); constsize_t_Space_size=(_Num_ptrs-1)*sizeof(void*);

_Num_ptrs值為10。

如果我們賦值的對(duì)象有成員變量會(huì)是什么情況呢?例如如下:

classCCaller { public: intoperator()(inta,intb,intc,intd) { std::cout<f; f=Caller; f(10,20,30,40); return0; }

內(nèi)存結(jié)構(gòu)如下:

333686e8-5788-11eb-8b86-12bb97331649.png

由此我們可以發(fā)現(xiàn)std::function是利用一個(gè)_Compressed_pair<_Alloc, _Callable> _Mypair;拷貝了元素的數(shù)據(jù)信息。

主要的初始化過(guò)程為:

emplate void_Reset_alloc(_Fx&&_Val,const_Alloc&_Ax) {//storecopyof_Valwithallocator if(!_Test_callable(_Val)) {//nullmemberpointer/functionpointer/std::function return;//alreadyempty } typedeftypenamedecay<_Fx>::type_Decayed; typedef_Func_impl<_Decayed,?_Alloc,?_Ret,?_Types...>_Myimpl; _Myimpl*_Ptr=0; typedef_Wrap_alloc<_Alloc>_Alimpl0; typedeftypename_Alimpl0::templaterebind<_Myimpl>::other_Alimpl; _Alimpl_Al(_Ax); _Reset_impl(_STDforward<_Fx>(_Val),_Ax, _Ptr,_Al,_Is_large<_Myimpl>()); }

其中decay<_Fx>::type定義了_Compressed_pair<_Alloc, _Callable> _Mypair;中_Callable的類型,這個(gè)聲明如下(也就是去掉引用和其他屬性信息):

template structdecay {//determinesdecayedversionof_Ty typedeftypenameremove_reference<_Ty>::type_Ty1; typedeftypename_If::value, typenameremove_extent<_Ty1>::type*, typename_If::value, typenameadd_pointer<_Ty1>::type, typenameremove_cv<_Ty1>::type>::type>::typetype; };

至此,我們大致上完成了std::function的原理分析了,希望在后續(xù)的使用中,我們能夠知道std::function在什么情況下可以使用,以及背后完成的事情。

責(zé)任編輯:lq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4363

    瀏覽量

    63770
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2116

    瀏覽量

    74528
  • 初始化
    +關(guān)注

    關(guān)注

    0

    文章

    50

    瀏覽量

    12025

原文標(biāo)題:C++ std::function 技術(shù)淺談

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C++學(xué)到什么程度可以找工作?

    C++學(xué)到什么程度可以找工作?要使用C++找到工作,特別是作為軟件開(kāi)發(fā)人員或相關(guān)職位,通常需要掌握以下幾個(gè)方面: 1. **語(yǔ)言基礎(chǔ)**:你需要對(duì)C++的核心概念有扎實(shí)的理解,包括但不限于指針、內(nèi)存
    發(fā)表于 03-13 10:19

    Spire.XLS for C++組件說(shuō)明

    Spire.XLS for C++ 是一款專業(yè)的 C++ Excel 組件,可以用在各種 C++ 框架和應(yīng)用程序中。Spire.XLS for C++ 提供了一個(gè)對(duì)象模型 Excel
    的頭像 發(fā)表于 01-14 09:40 ?438次閱讀
    Spire.XLS for <b class='flag-5'>C++</b>組件說(shuō)明

    EE-112:模擬C++中的類實(shí)現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《EE-112:模擬C++中的類實(shí)現(xiàn).pdf》資料免費(fèi)下載
    發(fā)表于 01-03 15:15 ?0次下載
    EE-112:模擬<b class='flag-5'>C++</b>中的類<b class='flag-5'>實(shí)現(xiàn)</b>

    AKI跨語(yǔ)言調(diào)用庫(kù)神助攻C/C++代碼遷移至HarmonyOS NEXT

    )開(kāi)發(fā)框架。它極大地簡(jiǎn)化了JS與C/C++之間的跨語(yǔ)言訪問(wèn),為開(kāi)發(fā)者提供了一種邊界性編程體驗(yàn)友好的解決方案。通過(guò)AKI,開(kāi)發(fā)者可以使用讓代碼更易讀的語(yǔ)法糖,實(shí)現(xiàn)JS與C/
    發(fā)表于 01-02 17:08

    運(yùn)動(dòng)控制卡周期上報(bào)實(shí)時(shí)數(shù)據(jù)IO狀態(tài)之C++

    使用C++進(jìn)行運(yùn)動(dòng)控制卡的周期上報(bào)功能實(shí)現(xiàn)
    的頭像 發(fā)表于 12-17 13:59 ?610次閱讀
    運(yùn)動(dòng)控制卡周期上報(bào)實(shí)時(shí)數(shù)據(jù)IO狀態(tài)之<b class='flag-5'>C++</b>篇

    同樣是函數(shù),在CC++中有什么區(qū)別

    同樣是函數(shù),在 CC++ 中有什么區(qū)別? 第一個(gè)返回值。 C語(yǔ)言的函數(shù)可以不寫返回值類型,編譯器會(huì)默認(rèn)為返回 int。 但是 C++ 的函數(shù),除了構(gòu)造和析構(gòu)這兩個(gè)特殊的函數(shù),必須
    的頭像 發(fā)表于 11-29 10:25 ?697次閱讀

    C7000 C/C++優(yōu)化指南用戶手冊(cè)

    電子發(fā)燒友網(wǎng)站提供《C7000 C/C++優(yōu)化指南用戶手冊(cè).pdf》資料免費(fèi)下載
    發(fā)表于 11-09 15:00 ?0次下載
    <b class='flag-5'>C</b>7000 <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>優(yōu)化指南用戶手冊(cè)

    TMS320C6000優(yōu)化C/C++編譯器v8.3.x

    電子發(fā)燒友網(wǎng)站提供《TMS320C6000優(yōu)化C/C++編譯器v8.3.x.pdf》資料免費(fèi)下載
    發(fā)表于 11-01 09:35 ?1次下載
    TMS320<b class='flag-5'>C</b>6000優(yōu)化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>編譯器v8.3.x

    C語(yǔ)言和C++中結(jié)構(gòu)體的區(qū)別

    同樣是結(jié)構(gòu)體,看看在C語(yǔ)言和C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?573次閱讀

    C7000優(yōu)化C/C++編譯器

    電子發(fā)燒友網(wǎng)站提供《C7000優(yōu)化C/C++編譯器.pdf》資料免費(fèi)下載
    發(fā)表于 10-30 09:45 ?0次下載
    <b class='flag-5'>C</b>7000優(yōu)化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>編譯器

    ostream在c++中的用法

    ostream 是 C++ 標(biāo)準(zhǔn)庫(kù)中一個(gè)非常重要的類,它位于 頭文件中(實(shí)際上,更常見(jiàn)的是通過(guò)包含 頭文件來(lái)間接包含 ,因?yàn)?包含了 和 )。 ostream 類及其派生類(如 std::cout
    的頭像 發(fā)表于 09-20 15:11 ?1445次閱讀

    基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的C++公共基礎(chǔ)類庫(kù)案例:SafeQueue

    1、程序簡(jiǎn)介該程序是基于OpenHarmony的C++公共基礎(chǔ)類庫(kù)的線程安全隊(duì)列:SafeQueue。線程安全隊(duì)列,是在dequeue的基礎(chǔ)上封裝std::lock_guard,以此實(shí)現(xiàn)線程的相關(guān)
    的頭像 發(fā)表于 08-30 12:41 ?513次閱讀
    基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的<b class='flag-5'>C++</b>公共基礎(chǔ)類庫(kù)案例:SafeQueue

    OpenVINO2024 C++推理使用技巧

    很多人都使用OpenVINO新版的C++ 或者Python的SDK,都覺(jué)得非常好用,OpenVINO2022之后的版本C++ SDK做了大量的優(yōu)化與整理,已經(jīng)是非常貼近開(kāi)發(fā)的使用習(xí)慣與推理方式。與OpenCV的Mat對(duì)象對(duì)接方式更是幾乎無(wú)縫對(duì)接,非常的方便好用。
    的頭像 發(fā)表于 07-26 09:20 ?1331次閱讀

    C++語(yǔ)言基礎(chǔ)知識(shí)

    電子發(fā)燒友網(wǎng)站提供《C++語(yǔ)言基礎(chǔ)知識(shí).pdf》資料免費(fèi)下載
    發(fā)表于 07-19 10:58 ?8次下載

    C++實(shí)現(xiàn)類似instanceof的方法

    C++有多態(tài)與繼承,但是很多人開(kāi)始學(xué)習(xí)C++,有時(shí)候會(huì)面臨一個(gè)常見(jiàn)問(wèn)題,就是如何向下轉(zhuǎn)型,特別是不知道具體類型的時(shí)候,這個(gè)時(shí)候就希望C++ 可以向Java或者Python中有insta
    的頭像 發(fā)表于 07-18 10:16 ?794次閱讀
    <b class='flag-5'>C++</b>中<b class='flag-5'>實(shí)現(xiàn)</b>類似instanceof的方法
    主站蜘蛛池模板: 中文永久免费看电视网站入口 | 国产精品久久久久久久9999 | 9久久99久久久精品齐齐综合色圆 | 亚洲成人网页 | 午夜高清在线观看免费6 | 女69女人poren25 | 人人97| 5151四虎永久在线精品免费 | 伊人久久狼人 | 午夜一级在线 | 97av在线播放| 操爽视频 | 成人免费淫片95视频观看网站 | 性欧美黑人巨大videos | 中文4480yy私人免费影院 | 天天操天天碰 | 欧美猛交xxx呻吟 | 狠狠欧美| 91精品日本久久久久久牛牛 | 拍拍拍美女黄色1000视频 | 天堂最新版资源www在线 | 男女爱爱福利 | 日韩三级免费观看 | 男人视频网 | 在线观看播放视频www | 欧美日韩不卡码一区二区三区 | 免费看黄色片网站 | 天天干天天操天天碰 | 国产精品视频一区国模私拍 | 国产免费成人在线视频 | 狠狠色噜噜狠狠狠狠米奇7777 | 亚洲va欧美va国产综合久久 | 午夜影视免费完整高清在线观看网站 | 在线资源天堂 | 国产精品午夜久久 | 丁香六月婷婷精品免费观看 | 日本黄色美女视频 | 在线视频一区二区三区 | 天堂一区二区三区在线观看 | 久久精品国产免费高清 | 天天综合网色 |