日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

std::cunction() 简单描述

發布時間:2024/3/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 std::cunction() 简单描述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

function是一組函數對象包裝類的模板,實現了一個泛型的回調機制。

引入頭文件

#include <functional>
using namespace std;
using namespace std::placeholders; ?//bind的時候會用`

參考:http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html

fuction ?bind:http://blog.csdn.net/fjb2080/article/details/7527715

我們可以調用的對象有很多,比如普通函數、函數指針、lanmbda表達式、函數對象和類的成員函數等。

不管采用哪種方式,主要調用形式一樣(返回值類型、傳遞給調用的實參類型),我們就可以使用同一種形式來調用。

這個時候就可以用到function模板,它給予我們在調用的方式上更大的彈性。

請看一下三種不同的函數定義:

[cpp] view plain copy
  • int?add(int?a,?int?b){??
  • ????return?a+b;??
  • }??
  • auto?mod=[](int?a,?int?b){return?a%b;};??
  • struct?divide{??
  • ????int?operator()(int?m,?int?n){??
  • ????????return?m/n;??
  • ????}??
  • };??
  • 這三種都可以使用同一種調用形式,int(int, int),調用方式如下:

    [cpp] view plain copy
  • function<int(int,int)>?func1=?add;??
  • function<int(int,int)>?func2=?divide();??
  • function<int(int,int)>?func3=?mod;??
  • cout<<func1(5,?6)<<endl;??
  • cout<<func2(5,?6)<<endl;??
  • cout<<func3(5,?6)<<endl;??

  • 學會了使用function,可以繼續如下進行抽象定義,不同類型采用相同的調用方法: [cpp] view plain copy
  • map<string,function<int(int,?int)>>?funs?=??
  • {??
  • ????{"+",?add},??
  • ????{"-",?std::minus<int>()},//標準庫的函數,參數為兩個整數,可以參考前一篇博客??
  • ????{"/",?divide()},//類成員函數??
  • ????{"*",?[](int?i,int?j){return?i*j;}},//lambda表達式??
  • ????{"%",?mod},??
  • };??
  • funs["+"](4,6);??

  • 以上就是function的簡單使用。下面是從另一篇博客轉載的,使用function的引用來保存函數對象。考慮下面代碼: [cpp] view plain copy
  • class?CAdd??
  • {??
  • public:??
  • ????CAdd():m_nSum(0){NULL;}??
  • ????int?operator()(int?i)??
  • ????{??
  • ????????m_nSum?+=?i;??
  • ????????return?m_nSum;??
  • ????}??
  • ??????
  • ????int?Sum()?const??
  • ????{??
  • ????????return?m_nSum;??
  • ????}??
  • ??????
  • private:??
  • ????int?m_nSum;??
  • };??
  • int?main(int?argc,?const?char?*?argv[])??
  • {??
  • ????CAdd?cAdd;??
  • ????function<int(int)>?funcAdd1?=?cAdd;??
  • ????function<int(int)>?funcAdd2?=?cAdd;??
  • ????cout<<funcAdd1(10)<<endl;??
  • ????cout<<funcAdd2(10)<<endl;??
  • ????cout<<cAdd.Sum()<<endl;??
  • ??????
  • ?????return?0;??
  • }??
  • 上面的輸出結果是 10 10 0。我們將同一個函數對象賦值給了兩個function,然后分別調用這兩個function,但函數中的成員變量的值沒有保存,問題在哪里?因為function的缺省行為是拷貝一份傳遞給它的函數對象,于是f1,f2中保存的都是cAdd對象的拷貝。

    C++11提供了ref和cref函數來提供對象的引用和常引用的包裝。要是function能夠正確保存函數對象的狀態,可以如下修改代碼:

    [cpp] view plain copy
  • function<int(int)>?funcAdd3?=?ref(cAdd);??
  • function<int(int)>?funcAdd4?=?ref(cAdd);??
  • cout<<funcAdd3(10)<<endl;??
  • cout<<funcAdd4(10)<<endl;??
  • cout<<cAdd.Sum()<<endl;??

  • ? ? ? ? 另外,兩個function之間賦值時,如果源function保存的是函數對象的拷貝,則目標function保存的也是函數對象的拷貝。如果源function保存的是對函數對象的引用,則目標function保存的也是函數對象的引用。

    //=====================================================================

    ? cplusplus.com:http://www.cplusplus.com/reference/functional/function/

    ? cppreference.com:http://en.cppreference.com/w/cpp/utility/functional/function

    std::function簡介


    ? 類模板聲明

    // MS C++ 2013 template<class _Fty> class function; template<class _Fty> class function : public _Get_function_impl<_Fty>::type { ... }// GCC 4.8.2 template<typename _Signature> class function; template<typename _Res, typename... _ArgTypes> class function<_Res(_ArgTypes...)>: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, private _Function_base { ... }

    // cplusplus.com
    template <class T> function; // undefined template <class Ret, class... Args> class function<Ret(Args...)>;

    ? 類模板說明

    ?????? std::function是一個函數包裝器模板,最早來自boost庫,對應其boost::function函數包裝器。在c++0x11中,將boost::function納入標準庫中。該函數包裝器模板能包裝任何類型的可調用元素(callable element),例如普通函數和函數對象。包裝器對象可以進行拷貝,并且包裝器類型僅僅只依賴于其調用特征(call signature),而不依賴于可調用元素自身的類型。

    ?????? 一個std::function類型對象實例可以包裝下列這幾種可調用元素類型:函數、函數指針、類成員函數指針或任意類型的函數對象(例如定義了operator()操作并擁有函數閉包)。std::function對象可被拷貝和轉移,并且可以使用指定的調用特征來直接調用目標元素。當std::function對象未包裹任何實際的可調用元素,調用該std::function對象將拋出std::bad_function_call異常

    ? 模板參數說明

    ?????? 以cplusplus.com中描述的原型說明:

    ???????T??????:?通用類型,但實際通用類型模板并沒有被定義,只有當T的類型為形如Ret(Args...)的函數類型才能工作。

    ???????Ret???: 調用函數返回值的類型。

    ???????Args?: 函數參數類型。

    std::function詳解


    ? 包裝普通函數

    #include <iostream> #include <functional> using namespace std;int g_Minus(int i, int j) {return i - j; }int main() {function<int(int, int)> f = g_Minus;cout << f(1, 2) << endl; // -1return 1; }

    ? 包裝模板函數

    #include <iostream> #include <functional> using namespace std;template <class T> T g_Minus(T i, T j) {return i - j; }int main() {function<int(int, int)> f = g_Minus<int>;cout << f(1, 2) << endl; // -1return 1; }

    ? 包裝lambda表達式

    #include <iostream> #include <functional> using namespace std;auto g_Minus = [](int i, int j){ return i - j; };int main() {function<int(int, int)> f = g_Minus;cout << f(1, 2) << endl; // -1return 1; }

    ? 包裝函數對象

    ?????? 非模板類型:

    #include <iostream> #include <functional> using namespace std;struct Minus {int operator() (int i, int j){return i - j;} };int main() {function<int(int, int)> f = Minus();cout << f(1, 2) << endl; // -1return 1; }

    ?????? 模板類型:

    #include <iostream> #include <functional> using namespace std;template <class T> struct Minus { T operator() (T i, T j){return i - j;} };int main() {function<int(int, int)> f = Minus<int>();cout << f(1, 2) << endl; // -1return 1; }

    ? 包裝類靜態成員函數

    ?????? 非模板類型:

    #include <iostream> #include <functional> using namespace std;class Math { public:static int Minus(int i, int j){return i - j;} };int main() {function<int(int, int)> f = &Math::Minus;cout << f(1, 2) << endl; // -1return 1; }

    ?????? 模板類型:

    #include <iostream> #include <functional> using namespace std;class Math { public:template <class T>static T Minus(T i, T j){return i - j;} };int main() {function<int(int, int)> f = &Math::Minus<int>;cout << f(1, 2) << endl; // -1return 1; }

    ? 包裝類對象成員函數

    ?????? 非模板類型:

    #include <iostream> #include <functional> using namespace std;class Math { public:int Minus(int i, int j){return i - j;} };int main() {Math m;function<int(int, int)> f = bind(&Math::Minus, &m, placeholders::_1, placeholders::_2);cout << f(1, 2) << endl; // -1return 1; }

    ?????? 模板類型:

    #include <iostream> #include <functional> using namespace std;class Math { public:template <class T>T Minus(T i, T j){return i - j;} };int main() {Math m;function<int(int, int)> f = bind(&Math::Minus<int>, &m, placeholders::_1, placeholders::_2);cout << f(1, 2) << endl; // -1return 1; }

    總結

    以上是生活随笔為你收集整理的std::cunction() 简单描述的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。