一元謂詞接受多個引數 lambda表示式的魅力

2021-07-22 18:35:18 字數 1753 閱讀 5114

首先我們引入乙個問題:

如果要你編乙個程式,使用find_if演算法來實現對乙個字串中的各個字元進行篩選並輸出符合特定長度的字元,你會怎麼辦?

有人會說這好辦,像下面這樣不就可以了嗎?

//省略部分內容,下同

find_if(str.begin(),str.end(),islength);

//...

bool islength(char c)

但是乙個靈活的程式需要有處理多變情況的能力,如果需要的特定長度不是乙個常量,而是需要從在程式執行時才能獲得值的變數,又應該怎麼辦?

當然我們首先會注意到find_if演算法原則上只接受一元謂詞,但從問題描述來說卻需要傳入兩個引數,乙個是字元,另乙個是儲存特定長度的變數,我的第乙個處理方法是將該變數宣告為全域性變數:

//相關標頭檔案

int len;

//...

bool islength(char c)

//...

find_if(str.begin(),str.end(),islength);

但是使用全域性變數也有缺點,一來是變數具有靜態儲存時期,但變數卻只在find_if中才發揮作用,一定程度浪費了記憶體空間,二來是要多次使用find_if時,需要新增的全域性變數宣告語句過多,使**冗雜。

因此,我們引入這篇文章的正題—使用lambda表示式。

lambda表示式,作為可呼叫物件之一,是乙個可呼叫的**單元,可視作內聯函式,可定義在函式內部。語法如下

[capture list](parameter list)->return type

lambda必須永遠包含捕獲列表和函式體,使用尾置返回指定返回型別。

尾置返回示例:auto func(int i)->int(*)[10];auto指示返回型別位於引數列表之後)

//值捕獲

void fcn1()

;v1=0;

auto j=f();//j=43

}

如果使用引用捕獲但是不想更改其值可以在該值宣告時加上const。

//引用捕獲

void fcn2()

;v1=0;

auto j=f();//j=1

}

transform(vi.begin(),vi.end(),vi.begin(),(int i));
上面程式編譯成功通過,但是如果程式改為下面這樣,就會出現編譯錯誤。

transform(vi.begin(),vi.end(),vi.begin(),(int i));
這是因為存在兩個return語句,且沒有指定返回型別,因此編譯器認定返回型別為void,然而實際卻返回int值。

指定返回型別後可以成功通過。

transform(vi.begin(),vi.end(),vi.begin(),(int i)->(int));
好了,讓我們回到一開始的問題,如何解決一元謂詞接受兩個引數(字元和長度)的問題。

//...

find_if(str.begin(), str.end(), [len](const char c));

//...

是不是省去了很多不必要的步驟呢?問題成功解決。

find if一元謂詞

find if接受一元謂詞,因此傳遞給find if的可呼叫物件必須接受單一引數。舉個例子 vector vec auto wc find if vec.begin vec.end sz const string words 當中的lambda表示式 sz const string words 轉化...

C 一元謂詞和二元謂詞

include include 演算法標頭檔案 include include using namespace std 返回型別為bool型別 的operator struct greatstruct for each需要使用的偽函式 template typename t void printer...

08 一元函式物件和一元謂詞

include using namespace std include string include include include set include include functional 函式物件 類過載了函式呼叫操作符,這樣的類定義的物件稱為函式物件 template class show...