色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

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

Linux愛好者 ? 來源:xdesk ? 作者:xdesk ? 2021-01-20 09:23 ? 次閱讀

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

std::function是一個函數(shù)對象的包裝器,std::function的實例可以存儲,復制和調(diào)用任何可調(diào)用的目標,包括:

函數(shù)。

lamada表達式。

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

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

當std::function對象沒有初始化任何實際的可調(diào)用元素,調(diào)用std::function對象將拋出std::bad_function_call異常。

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

1. std::function簡介

在討論其原理的時候,我們來熟悉一下這個東西是怎么使用的,C++標準庫詳細說明了這個的基本使用http://www.cplusplus.com/reference/functional/function/.

這里我們大概總結一下。

1.1 Member types

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

1.2 Member functions

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

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)用類對象。

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

在標準庫中STL設計為如下:

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繼承關系比較簡單,主要使用

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

這個來存儲我們設置的可調(diào)用對象,我們從std::function的使用過程看一下整個原理。

2.1 函數(shù)對象賦值

我們使用的時候一般使用f = Caller;來設置函數(shù)對象,我們看下這個的實現(xiàn)過程。

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

我們看this->_Reset(_Func)這個函數(shù),因為這個才是設置函數(shù)可調(diào)用對象的東西。

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()); }

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

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

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

調(diào)用操作主要是通過operator()來實現(xiàn)的,我們看下這個的實現(xiàn)過程。

_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)...)); }

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

2.3 _Func_impl的實現(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這個類通過_Do_call來轉(zhuǎn)發(fā)函數(shù)對象的調(diào)用操作。

3. 總結

這里我們看下std::function的結構信息,如下:

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。

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

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

內(nèi)存結構如下:

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

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

主要的初始化過程為:

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的類型,這個聲明如下(也就是去掉引用和其他屬性信息):

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在什么情況下可以使用,以及背后完成的事情。

責任編輯:lq

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

    關注

    3

    文章

    4327

    瀏覽量

    62573
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73622
  • 初始化
    +關注

    關注

    0

    文章

    50

    瀏覽量

    11850

原文標題:C++ std::function 技術淺談

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    運動控制卡周期上報實時數(shù)據(jù)IO狀態(tài)之C++

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

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

    電子發(fā)燒友網(wǎng)站提供《C7000 C/C++優(yōu)化指南用戶手冊.pdf》資料免費下載
    發(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語言和C++中結構體的區(qū)別

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

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

    電子發(fā)燒友網(wǎng)站提供《C7000優(yōu)化C/C++編譯器.pdf》資料免費下載
    發(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++ 標準庫中一個非常重要的類,它位于 頭文件中(實際上,更常見的是通過包含 頭文件來間接包含 ,因為 包含了 和 )。 ostream 類及其派生類(如 std::cout
    的頭像 發(fā)表于 09-20 15:11 ?663次閱讀

    OpenVINO2024 C++推理使用技巧

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

    C++語言基礎知識

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

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

    C++有多態(tài)與繼承,但是很多人開始學習C++,有時候會面臨一個常見問題,就是如何向下轉(zhuǎn)型,特別是不知道具體類型的時候,這個時候就希望C++ 可以向Java或者Python中有insta
    的頭像 發(fā)表于 07-18 10:16 ?574次閱讀
    <b class='flag-5'>C++</b>中<b class='flag-5'>實現(xiàn)</b>類似instanceof的方法

    C/C++中兩種宏實現(xiàn)方式

    #ifndef的方式受C/C++語言標準支持。它不僅可以保證同一個文件不會被包含多次,也能保證內(nèi)容完全相同的兩個文件(或者代碼片段)不會被不小心同時包含。
    的頭像 發(fā)表于 04-19 11:50 ?605次閱讀

    鴻蒙OS開發(fā)實例:【Native C++

    使用DevEco Studio創(chuàng)建一個Native C++應用。應用采用Native C++模板,實現(xiàn)使用NAPI調(diào)用C標準庫的功能。使用C
    的頭像 發(fā)表于 04-14 11:43 ?2593次閱讀
    鴻蒙OS開發(fā)實例:【Native <b class='flag-5'>C++</b>】

    使用 MISRA C++:2023? 避免基于范圍的 for 循環(huán)中的錯誤

    在前兩篇博客中,我們?向您介紹了新的 MISRA C++ 標準?和?C++ 的歷史?。在這篇博客中,我們將仔細研究以 C++ 中?for?循環(huán)為中心的特定規(guī)則。
    的頭像 發(fā)表于 03-28 13:53 ?785次閱讀
    使用 MISRA <b class='flag-5'>C++</b>:2023? 避免基于范圍的 for 循環(huán)中的錯誤

    verilog task和function區(qū)別

    verilog中的task和function都是用于實現(xiàn)模塊中的可重復的功能,并且可以接收參數(shù)和返回結果。但是它們在編寫和使用上有一些區(qū)別。下面將詳細介紹task和function的區(qū)別。 語法結構
    的頭像 發(fā)表于 02-22 15:53 ?1058次閱讀

    c語言,c++,java,python區(qū)別

    C語言、C++、Java和Python是四種常見的編程語言,各有優(yōu)點和特點。 C語言: C語言是一種面向過程的編程語言。它具有底層的特性,能夠?qū)τ嬎銠C硬件進行直接操作。
    的頭像 發(fā)表于 02-05 14:11 ?2366次閱讀

    vb語言和c++語言的區(qū)別

    VB語言和C++語言是兩種不同的編程語言,雖然它們都屬于高級編程語言,但在設計和用途上有很多區(qū)別。下面將詳細比較VB語言和C++語言的區(qū)別。 設計目標: VB語言(Visual Basic)是由
    的頭像 發(fā)表于 02-01 10:20 ?2258次閱讀

    C++簡史:C++是如何開始的

    MISRA C++:2023,MISRA? C++ 標準的下一個版本,來了!為了幫助您做好準備,我們介紹了 Perforce 首席技術支持工程師 Frank van den Beuken 博士撰寫
    的頭像 發(fā)表于 01-11 09:00 ?581次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的
    主站蜘蛛池模板: 最新无码国产在线视频2020| 亚洲AV国产福利精品在现观看 | 亚洲A片不卡无码久久尤物| 亚洲欧美综合乱码精品成人网| 国产一区二区青青精品久久| 99久久做夜夜爱天天做精品| 办公室沙发口爆12P| jizz日本黄色| 国产亚洲免费观看| WWW国产亚洲精品久久| 在线少女漫画| 亚洲色图p| 亚洲haose在线观看| 天天澡夜夜澡人人澡| 色婷婷五月综合中文字幕| 恋夜秀场1234手机视频在线观看| 国产一区在线观看免费| 久久精品视频在线直播6| 涩涩涩涩爱网站| 亚洲午夜性春猛交XXXX | 亚洲1卡二卡3卡4卡新区在线| 2019在秋霞理论| 国产精品系列在线一区| 欧美成人精品高清在线观看| 亚洲高清免费在线观看| 55夜色66夜亚洲精品播放| 国内精品人妻无码久久久影院蜜桃 | 日日噜噜夜夜躁躁狠狠| 在线精彩视频在线观看免费| 国产精片久久久久久婷婷| 久久天天婷婷五月俺也去| 色窝窝777欧美午夜精品影院| 6080YYY午夜理论片在线观看| 国产在线观看网址你懂得| 日日摸夜夜添无码AVA片| 5g在视影讯天天5g免费观看| 国内精品久久久久影院老司| 熟女少妇内射日韩亚洲| gv手机在线观看| 美女与男人对肌免费网站| 亚洲一卡二卡三卡四卡2021麻豆|