小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

(原創(chuàng))C++11改進(jìn)我們的程序之簡(jiǎn)化我們的程序(五)

 碼農(nóng)書(shū)館 2019-02-19

這次要講的是:c++11中的bind和function

std::function

它是函數(shù)、函數(shù)對(duì)象、函數(shù)指針、和成員函數(shù)的包裝器,可以容納任何類型的函數(shù)對(duì)象,函數(shù)指針,引用函數(shù),成員函數(shù)的指針。
以統(tǒng)一的方式處理函數(shù)、函數(shù)對(duì)象、函數(shù)指針、和成員函數(shù)。
允許保存和延遲執(zhí)行函數(shù)。

  • 函數(shù)和成員函數(shù)作為function
復(fù)制代碼
void G();
struct A
{
void H(){}
};

std::function<void()> f = G; //全局函數(shù)

A a;
std::function<void()> f 1= std::bind(&A::H, a); //成員函數(shù)
復(fù)制代碼
  • 可以用function取代函數(shù)指針。因?yàn)樗梢员4婧瘮?shù)延遲執(zhí)行,所以比較適合作為回調(diào)函數(shù),也可以把它看做類似于c#中特殊的委托,只有一個(gè)成員的委托。
復(fù)制代碼
struct A
{
A(std::function<void()>& f):m_callback(f)
void Notify()
{
m_callback();//回調(diào)到上層
}

std::function<void()> m_callback;
}
復(fù)制代碼
  • function還可以作為函數(shù)入?yún)?,這樣可以在函數(shù)外部控制函數(shù)的內(nèi)部行為了,讓我們的函數(shù)變得更加靈活。
復(fù)制代碼
void Foo(int x, std::function<void(int)>& f)
{
if(x%2==0)
f(x);
}

void G(int x)
{
cout<<x<<endl;
}

void H(int x)
{
cout<<x+2<<endl;
}

void TestFoo()
{
auto f = std::bind(G, std::placeholders::_1); 
Foo(4, f);

//在Foo函數(shù)外面更改f的行為
f = std::bind(H, std::placeholders::_1);
Foo(4, f);
}
復(fù)制代碼

std::bind綁定器

  • 將函數(shù)、成員函數(shù)和閉包轉(zhuǎn)成function函數(shù)對(duì)象
  • 將多元(n>1)函數(shù)轉(zhuǎn)成一元函數(shù)或者(n-1)元函數(shù)。
復(fù)制代碼
void H(int a);
//綁定全局函數(shù)
auto f11 = std::bind(H, std::placeholders::_1);
auto的類型實(shí)際上是std::function<void(int)>

//綁定帶參數(shù)的成員函數(shù)
std::function<void (char*, int)> f = std::bind(&ReadHandler::ConnectPreProcess, this, std::placeholders::_1, std::placeholders::_1);

//三元函數(shù)轉(zhuǎn)換成一元函數(shù)
int f(int, char, double);
// 綁定f()函數(shù)調(diào)用的第二個(gè)和第三個(gè)參數(shù),
// 返回一個(gè)新的函數(shù)對(duì)象為ff,它只帶有一個(gè)int類型的參數(shù)
auto ff = bind(f, _1, ‘c’, 1.2);    
int x = ff(7); 
復(fù)制代碼
  • bind簡(jiǎn)化和增強(qiáng)bind1st和bind2nd

  其實(shí)bind簡(jiǎn)化和增強(qiáng)了之前標(biāo)準(zhǔn)庫(kù)中bind1st和bind2nd,它完全可以替代bind1s和bind2st,并且能組合函數(shù)。我們知道bind1st和bind2nd將一個(gè)二元算子轉(zhuǎn)換成一個(gè)一元算子。

//查找元素值大于10的元素的個(gè)數(shù)
int count = count_if(coll.begin(), coll.end(), std::bind1st(less<int>(), 10));
//查找元素之小于10的元素
int count = count_if(coll.begin(), coll.end(), std::bind2nd(less<int>(), 10));

  本質(zhì)上是對(duì)一個(gè)二元函數(shù)less<int>的調(diào)用,但是它卻要分別用bind1st和bind2nd,而且還要想想到底是用bind1st還是bind2nd,用起來(lái)感覺(jué)不方便。現(xiàn)在用bind,就可以以統(tǒng)一的方式去實(shí)現(xiàn)了。

//查找元素值大于10的元素的個(gè)數(shù)
int count = count_if(coll.begin(), coll.end(), bind(less<int>(), 10, _1));
//查找元素之小于10的元素
int count = count_if(coll.begin(), coll.end(), bind(less<int>(), _1, 10));
這樣我就不用關(guān)心到底是用bind1st還是bind2nd了,只要用bind就都搞定了。
  • bind函數(shù)組合

bind的還有一個(gè)強(qiáng)大之處就是函數(shù)組合。假設(shè)我們要找出集合中大于5小于10的元素個(gè)數(shù)怎么做呢?我們需要一個(gè)邏輯與才能做到類似于:

std::bind(std::logical_and<bool>(),_1,_2);

然后,我們需要另一個(gè)謂詞來(lái)回答 _1 是否大于5。

std::bind(std::greater<int>(),_1,5);

然后,我們還需要另一個(gè)謂詞來(lái)回答 _1 是否小于等于10。

std::bind(std::less_equal<int>(),_1,10);

最后,我們需要把它們兩個(gè)用邏輯與合起來(lái),就象這樣:

//查找集合中大于5小于10的元素個(gè)數(shù)
auto f = bind(std::logical_and<bool>(), bind(std::greater<int>(),_1,5), bind(std::less_equal<int>(),_1,10));
int count = count_if(coll.begin(), coll.end(), f);

  c++11中推出function是為了泛化函數(shù)對(duì)象,函數(shù)指針,引用函數(shù),成員函數(shù)的指針,讓我們可以按更統(tǒng)一的方式寫(xiě)出更加泛化的代碼;推出bind是為了替換和增強(qiáng)之前標(biāo)準(zhǔn)庫(kù)的bind1st和bind2st,讓我們的用起來(lái)更方便!

c++11 boost技術(shù)交流群:296561497,歡迎大家來(lái)交流技術(shù)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多