最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++11中綁定器bind的原理與使用

 更新時(shí)間:2022年12月09日 10:36:52   作者:Hello_Bugs  
C++11中引入的function機(jī)制,其中綁定器主要有三種:bind1st、bind2nd、bind(C++11)。本文就來和大家聊聊這些綁定器的底層實(shí)現(xiàn)原理與使用場景,需要的可以參考一下

bind1st和bind2nd什么時(shí)候會(huì)用到

bind用于綁定可調(diào)用 (Callable) 對象(函數(shù)對象、指向函數(shù)指針、到函數(shù)引用、指向成員函數(shù)指針或指向數(shù)據(jù)成員指針)和其參數(shù)。返回值為綁定成功后的函數(shù)對象

C++11中引入的function機(jī)制,其中綁定器主要有三種:bind1st、bind2nd、bind(C++11)

函數(shù)對象

盡管函數(shù)指針被廣泛用于實(shí)現(xiàn)函數(shù)回調(diào),但C++還提供了一個(gè)重要的實(shí)現(xiàn)回調(diào)函數(shù)的方法,那就是函數(shù)對象。函數(shù)對象(也稱“函數(shù)符”)是重載了“()”操作符的普通類對象。因此從語法上講,函數(shù)對象與普通的函數(shù)行為類似。
用函數(shù)對象代替函數(shù)指針有幾個(gè)優(yōu)點(diǎn):

首先,因?yàn)閷ο罂梢栽趦?nèi)部修改而不用改動(dòng)外部接口,因此設(shè)計(jì)更靈活,更富有彈性。函數(shù)對象也具備有存儲(chǔ)先前調(diào)用結(jié)果的數(shù)據(jù)成員。在使用普通函數(shù)時(shí)需要將先前調(diào)用的結(jié)果存儲(chǔ)在全程或者本地靜態(tài)變量中,但是全程或者本地靜態(tài)變量有某些我們不愿意看到的缺陷。

其次,在函數(shù)對象中編譯器能實(shí)現(xiàn)內(nèi)聯(lián)調(diào)用,從而更進(jìn)一步增強(qiáng)了性能。這在函數(shù)指針中幾乎是不可能實(shí)現(xiàn)的。

C++11還提供了limbda表達(dá)式來實(shí)現(xiàn)函數(shù)的靈活調(diào)用。詳見《C++ Primer Plus》第18章

函數(shù)對象實(shí)際上是類調(diào)用operator()()小括號(hào)運(yùn)算符重載,實(shí)現(xiàn)像在“調(diào)用函數(shù)”一樣的效果,因此還有個(gè)別名叫“仿函數(shù)”。函數(shù)對象示例代碼如下:

class Print {
public:
    void operator()(string &s) { cout << s << endl; }
};

int main() {
    string s = "hello world!";
    Print print; //定義了一個(gè)函數(shù)對象print
    print(s);
    return 0;
}

上面代碼print(s);語句,看似像函數(shù)調(diào)用,其實(shí)是類對象print調(diào)用其小括號(hào)運(yùn)算符重載print.operator(string &s)。print就是一個(gè)函數(shù)對象,至此對函數(shù)對象就有了基本的認(rèn)識(shí)

為什么需要綁定器?在使用STL時(shí)經(jīng)常會(huì)遇到STL算法中需要傳遞某元函數(shù)對象,比如在寫sort時(shí),第三個(gè)參數(shù)決定了我們的排序規(guī)則,用來接收一個(gè)“比較器”函數(shù)對象,該函數(shù)對象是一個(gè)二元的匿名函數(shù)對象,形如greator()或者less()。二元函數(shù)對象的意思是,這個(gè)函數(shù)對象的小括號(hào)運(yùn)算符重載函數(shù)接收兩個(gè)參數(shù),那么幾元就表示接收幾個(gè)參數(shù)。

我們知道系統(tǒng)自帶的greater()和less()模板類對象是二元匿名函數(shù)對象,但是像泛型算法find_if第三個(gè)參數(shù)接收一元函數(shù)對象,所以需要通過綁定器將其轉(zhuǎn)換為一元函數(shù)對象,可以通過bind1st和bind2nd去綁定,顧名思義,前者對二元函數(shù)對象的第一個(gè)參數(shù)進(jìn)行綁定,后者對二元函數(shù)對象的第二個(gè)參數(shù)進(jìn)行綁定,兩個(gè)綁定器均返回一元函數(shù)對象

sort(vec.begin(), vec.end(), greater<int>()); //從大到小對vector進(jìn)行排序
find\_if(vec.begin(), vec.end(), bind1st(greater<int>(), 70));
find\_if(vec.begin(), vec.end(), bind2nd(less<int>(), 70));

下面給出bind1st綁定過程圖,二元函數(shù)對象綁定了第一個(gè)數(shù)為70,變?yōu)橐辉瘮?shù)對象,傳遞給find_if泛型算法,此時(shí)find_if所實(shí)現(xiàn)的功能就是:找出有序降序數(shù)組中第一個(gè)小于70的數(shù),所以find_if返回指向65元素的迭代器

綁定器

C++ STL

bind1st 將operator()的第一個(gè)形參綁定成一個(gè)確定的值

bind2nd 將operator()的第二個(gè)形參綁定成一個(gè)確定的值

代碼1

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;


template<typename Container>

void printerContainer(Container  & _container) {

	typename Container::iterator it_begin = _container.begin();
	typename Container::iterator it_end   = _container.end();
	while (it_begin != it_end) {
		cout << *it_begin <<" " ;
		++it_begin;
	}

}

int main() {

	vector < int>  vec;
	srand(time(nullptr));
	for (int i = 0; i < 20; i++) {
		vec.push_back((rand() % 100 + 1));		
	}

	printerContainer<vector < int>>(vec);

	vector< int>::iterator it_begin= vec.begin();
	vector< int>::iterator it_end  = vec.end();

	sort(it_begin, it_end);//默認(rèn)小到大排序
	cout << endl;
	printerContainer<vector < int>>(vec);

	cout << endl;
	//greater二元函數(shù)對象
	sort(it_begin, it_end,greater<int>());//大到小排序
	printerContainer<vector < int>>(vec);

	cout << endl;

	//將70按順序插入容器中,找到第一個(gè)小于70的元素
	//庫里提供的less,greater都是二元的函數(shù)對象
	//greater a>b
	//less    a<b;
	//綁定器   + 二元函數(shù)對象 => 一元函數(shù)對象
	
	//bind1st: + greater bool operator()(70, const _Ty& _Right) 	
	//greater
	//constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
	//{	// apply operator> to operands
	//	return (_Left > _Right);
	//}
 
	//bind2nd: + less bool operator()(const _Ty& _Left, 70) 

	vector<int>::iterator  it_findValue=find_if(it_begin, it_end, bind1st<greater<int>, int>(greater<int>(), 70));
	if (it_findValue != it_end) {
		vec.insert(it_findValue, 70);
	}
	printerContainer<vector < int>>(vec);

	cout << endl;

	system("pause");

	return 0;
}

綁定器 + 二元函數(shù)對象 => 一元函數(shù)對象

bind1st和bind2nd的底層實(shí)現(xiàn)原理

自己實(shí)現(xiàn)綁定器,代碼如下

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <ctime>
using namespace std;

template<typename Container>
void printContainter(Container _container) {
	typename Container::iterator  it_begin = _container.begin();
	typename Container::iterator  it_end = _container.end();

	for (; it_begin != it_end; ++it_begin) {
		cout << *it_begin << " ";
	}
	cout << endl;
}


//將二元函數(shù)對象分裝,返回一元函數(shù)對象
template<typename Pr, typename T>
class MyBindList2 {

public:
	MyBindList2<Pr,T>(Pr _pr, T _val):_mPr(_pr),_mVal(_val) {}
	bool operator()(T _paremeter) {
		return _mPr(_mVal, _paremeter);
	}
private:
	Pr _mPr;
	T  _mVal;
};

//Iterator 迭代器
//Pr 一元函數(shù)對象
template<typename Iterator , typename Pr>
Iterator my_find_if_v2(Iterator it_begin, Iterator it_end, Pr _pre) {
	for (; it_begin != it_end; ++it_begin) {
		if (_pre(*it_begin)) { return it_begin; }
	}
	return it_end;
}



int main() {

	vector<int> v1;
	srand(time(nullptr));
	for (int i = 0; i < 10; i++) {
		v1.push_back((rand() % 100 + 1));
	}

	printContainter<vector<int>>(v1);

	//升序
	sort(v1.begin(), v1.end(), less<int>());

	//sort(v1.begin(), v1.end(), greater<int>()); 降序

	printContainter<vector<int>>(v1);



	/* 找到第一個(gè)大于40數(shù)字前插入40 */
	//  方法 一
    #if 0

	vector<int>::iterator it_begin = v1.begin();
	vector<int>::iterator it_end   = v1.end();

	for (; it_begin!=it_end; ++it_begin) {
		if (*it_begin > 40) {  break ;}
	}
	if (it_begin != it_end) {
		v1.insert(it_begin,40);
	}
	printContainter<vector<int>>(v1);
   #endif 


 	//  方法 二 自己實(shí)現(xiàn)Bind1st
    #if 0 自己實(shí)現(xiàn)Bind1st
	vector<int>::iterator it_find = my_find_if_v2<vector<int>::iterator, MyBindList2<less<int>, int>>(v1.begin(), v1.end(), MyBindList2<less<int>, int>(less<int>(), 40));

	v1.insert(it_find, 40);

	printContainter<vector<int>>(v1);

    #endif 

	//  方法 三  調(diào)用庫的Bind1st

    vector<int>::iterator find_it2=find_if<vector<int>::iterator, binder1st<less<int>>>(v1.begin(), v1.end(), bind1st<less<int>, int>(less<int>(), 40));
	v1.insert(find_it2, 40);

	printContainter<vector<int>>(v1);

	system("pause");
	return 0;



}

上面代碼自己實(shí)現(xiàn)泛型算法my_find_if,用于找到容器中指定的位置,插入元素my_find_if 是一個(gè)函數(shù)模板,參數(shù)1,參數(shù)2是兩個(gè)迭代器指向起始和結(jié)束位置,在這兩個(gè)迭代器之間進(jìn)行遍歷,遍歷是否滿足的條件由第三個(gè)參數(shù)決定,第三個(gè)參數(shù)是一個(gè)一元函數(shù)對象,由于STL現(xiàn)成提供的greater,less都是二元函數(shù)對象,所以我們自己需要實(shí)現(xiàn)一元函數(shù)對象,這個(gè)一元函數(shù)對象通過提供的二元函數(shù)對象和參數(shù)進(jìn)行封裝,封裝后就是myBind1st,myBind1st底層 operator()(parameter1) 中實(shí)際調(diào)用的函數(shù)二元函數(shù)對象的operator()( parameter1 ,parameter2)

vector<int>::iterator it_findValue = my_find_if(it_begin, it_end, myBind1st<greater<int>, int>(greater<int>(), 70));

以上就是詳解C++11中綁定器bind的原理與使用的詳細(xì)內(nèi)容,更多關(guān)于C++11綁定器bind的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Qt使用Quazip解壓縮、壓縮文件的實(shí)現(xiàn)

    Qt使用Quazip解壓縮、壓縮文件的實(shí)現(xiàn)

    Quazip是在zlib基礎(chǔ)上進(jìn)行了簡單封裝的開源庫,利用它可以很方便將單個(gè)或多個(gè)文件打包為zip文件,本文主要介紹了Qt使用Quazip解壓縮、壓縮文件的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • C++內(nèi)存池的簡單實(shí)現(xiàn)

    C++內(nèi)存池的簡單實(shí)現(xiàn)

    內(nèi)存池是一種動(dòng)態(tài)內(nèi)存分配與管理技術(shù)。本文主要介紹了C++內(nèi)存池的簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • C語言實(shí)現(xiàn)順序表的全操作詳解

    C語言實(shí)現(xiàn)順序表的全操作詳解

    順序表,全名順序存儲(chǔ)結(jié)構(gòu),是線性表的一種,線性表用于存儲(chǔ)邏輯關(guān)系為“一對一”的數(shù)據(jù),順序表自然也不例外,不僅如此,順序表對數(shù)據(jù)的物理存儲(chǔ)結(jié)構(gòu)也有要求,跟隨下文來具體了解吧
    2022-04-04
  • 關(guān)于C++內(nèi)存中字節(jié)對齊問題的詳細(xì)介紹

    關(guān)于C++內(nèi)存中字節(jié)對齊問題的詳細(xì)介紹

    本篇文章是對C++內(nèi)存中字節(jié)對齊的問題進(jìn)行了詳細(xì)的分析與總結(jié)。需要的朋友參考下
    2013-05-05
  • 單元測試代碼覆蓋率解析

    單元測試代碼覆蓋率解析

    單元測試(unit testing),是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證。動(dòng)態(tài)分析就是通過觀察軟件運(yùn)行時(shí)的動(dòng)作,來提供執(zhí)行跟蹤,時(shí)間分析,以及測試覆蓋度方面的信息。下面我們來詳細(xì)了解下吧
    2019-06-06
  • 基于C語言實(shí)現(xiàn)見縫插針游戲的示例代碼

    基于C語言實(shí)現(xiàn)見縫插針游戲的示例代碼

    見縫插針游戲就是使用鼠標(biāo)左鍵點(diǎn)擊發(fā)射針,當(dāng)兩個(gè)針的夾角小于一定限制時(shí),游戲結(jié)束。本文將用C語言實(shí)現(xiàn)這一有趣游戲,感興趣的可以了解一下
    2022-11-11
  • C語言詳解結(jié)構(gòu)體的內(nèi)存對齊與大小計(jì)算

    C語言詳解結(jié)構(gòu)體的內(nèi)存對齊與大小計(jì)算

    C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對齊與計(jì)算大小
    2022-04-04
  • linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹

    linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹

    這篇文章主要介紹了linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 深入理解雙指針的兩種用法

    深入理解雙指針的兩種用法

    本篇文章是對雙指針的兩種用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++?sqlite3數(shù)據(jù)庫配置使用教程

    C++?sqlite3數(shù)據(jù)庫配置使用教程

    SQLite 是一種嵌入式的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它是一個(gè)開源項(xiàng)目,已經(jīng)被廣泛應(yīng)用于各種應(yīng)用程序和操作系統(tǒng)中,這篇文章主要介紹了C++?sqlite3數(shù)據(jù)庫配置使用,需要的朋友可以參考下
    2023-08-08

最新評論

工布江达县| 莲花县| 萍乡市| 华宁县| 朝阳区| 淅川县| 宜宾县| 津市市| 顺昌县| 衢州市| 辽源市| 铜陵市| 资阳市| 德惠市| 金川县| 永宁县| 洞口县| 综艺| 兴宁市| 时尚| 敦化市| 通海县| 扶绥县| 时尚| 台北县| 璧山县| 西林县| 罗平县| 盘山县| 长治市| 荥经县| 玛多县| 绍兴县| 华蓥市| 招远市| 香格里拉县| 龙海市| 望谟县| 炉霍县| 东山县| 连平县|