C++的標準庫STL里面有6大部件,其中之一為仿函式,初始看到這一名字可能讓人摸不著頭腦:函式倒是挺容易理解,何故又起個仿函式的名字呢?本文將帶你揭開它看起來挺讓人迷惑但是實際上很簡單的面紗,
仿函式,看名字就知道它肯定和函式有什么關聯,但是也肯定和函式有什么區別,函式主要是一塊接收輸入引數然后按照一定邏輯組織起來計算輸出引數的程序(這里把print之類的也稱為輸出引數,只不過是輸出到螢屏上或者檔案中),簡而言之就是一個執行特定功能的代碼塊,仿函式也是執行特定功能的代碼塊,但是與函式不同的是,仿函式寫的形式看起來有一些不一樣,下面看一個簡單例子:
1 template<T> 2 struct plus{ 3 T operator()(const T&x,const T& y){ 4 return x+y; 5 } 6 }
這段代碼的主要功能是實作一個加的功能,從名字也可以輕易地看出來,從代碼的具體結構看,仿函式寫了一個類,這個類的名字叫plus,類中僅有一個operator()的實作,目前為止仿函式看起來雖然挺簡單,但是好像沒啥用啊!!官人別急,馬上就上菜了,
介紹仿函式的用途之前,有必要介紹一下無名物件,
在C++中無名物件是非常常見的,不過很多時候我們并不會注意到它的存在,例如下面一個例子:
int len(std::string str){ return str.size(); }
當我們在引數傳遞時,編譯器實際上做的事是拷貝呼叫的時候傳遞的引數一份,然后利用拷貝的資料進行操作,這里就會涉及到無名物件(實際上一個無名的string,我們不妨利用一下python的思想,把所有東西都看成是物件),根據以上的說法,上面這以函式與一下的函式使用有不同之處:
1 int len(std::string& str){ 2 return str.size(); 3 }
這里我們僅僅是加了一個按參考傳遞的符號,這時再呼叫len(str),程序就應該不一樣了,如果各位看官想要測驗,可以重寫一下new方法:
1 void* operator new(size_t size){ 2 std::cout<<"Allocating: "<<size<<" bytes"<<std::endl; 3 return malloc(size); 4 }
這時一旦有new方法被呼叫,則我們就可以看到輸出資訊,說明進行了記憶體的申請操作,具體測驗請各位大爺自行測驗,
事實上,C++17標準增加了一個string_view類,可以使用此類達到一些特定的string的引數傳遞作用,例如我們只是想要比較一下字串中部分字符,那么使用string_view是不錯的選擇,再如我們都知道再使用vector容器時,可以使用.push_back()方法追加元素,也有一個非常類似的方法:.emplace_back();實作的功能也是追加元素,不同之處在于push_back會創建一個無名物件但是emplace_back不會,具體測驗也請各位大爺利用上面寫的new方法進行測驗,
啰嗦了一大堆,無名物件跟仿函式有什么卵關系呢?
實際上仿函式最常用的也是無名物件的形式,舉個例子,再algorithm頭檔案中,有一個經常用到的方法叫做sort,該方法默認功能是給指定容器的元素按照從小到大的順序排序,那么問題來了,如果我們想要從大到小排序呢?或者對于矩陣我們想要不按第一列,而是按照某一列排序呢?這時仿函式就可以發揮作用了,對于上述的問題,通常程式大爺的解決方法是寫一個lamda函式(不知道的大爺喝口雪碧)或者自己寫一下cmp方法作為sort函式的第三個引數,實際上這一cmp方法也可以用仿函式試現,
以上拿sort方法舉例了,實際上,其他方法也完全可以使用,或者我們再寫東西的時候,也可以寫自己的仿函式,下面舉一個純粹使用仿函式的例子:
1 int main(){ 2 plus<int> p; 3 std::cout<<p(2,3)<<std::endl; 4 std::cout<<plus<int>(2,3)<<std::endl; 5 }
講到這里應該比較清楚了吧各位大爺?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/27265.html
標籤:C++
上一篇:類歐幾里得演算法
