2016-04-27 27 views
6

我不明白爲什麼第三種情況是好的(即使lambda的參數類型與std::function類型不同),而編譯器會抱怨第四種情況:來自std :: function的不同簽名的Lambda函數

function<int(int)> idInt = [](int i) {return i;}; //OK 
function<int(int&)> idInt = [](int &i) {return i;}; //OK 
function<int(int&)> idInt = [](int i) {return i;}; //OK 
function<int(int)> idInt = [](int &i) {return i;}; //ERROR! 
+5

因爲:

auto fn = [](int &i) {return i;}; fn(1); // error - you try to bind temporary to reference 

可以通過更改簽名使用右值引用或const &修復存在從左值到右值的轉換(即所謂的「左值到右值轉換」),但是不存在從右值到左值的轉換。 'std :: function'的構造函數不關心聲明的簽名,而僅僅關於隱含的* call表達式*是否有效。 –

+2

爲什麼不使用'auto'? 'auto idInt = ...' – ZDF

回答

8

當你寫:

function<int(int)> idInt = [](int &i) {return i;}; //ERROR! 

然後你說idInt可以包裝的功能,關閉,..可與int參數來調用。但是,這是不是在[](int &i) {return i;};情況下真實的,因爲你不能用積分字面稱呼它喜歡這裏:

std::function<int(int)> idInt1 = [](int &&i) {return i;}; 
std::function<int(int)> idInt2 = [](const int &i) {return i;}; 
相關問題