2016-04-27 10 views
6

Nie rozumiem dlaczego trzeci przypadek jest ok (nawet jeśli lambda za argumenty typu różni się od typu std::function są), podczas gdy kompilator narzeka z czwartym:funkcja Lambda z różnych podpisów z std :: funkcji

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

Bo istnieje konwersja z lwartości do rwartości (tak zwana "konwersja l-wartości do r-wartości"), ale nie ma konwersji z wartości r na wartość l. Konstruktory 'std :: function' nie dbają o zadeklarowane sygnatury, tylko o to, czy dorozumiane * wyrażenie wywołania * jest poprawne. –

+2

Dlaczego nie używać 'auto'? 'auto idInt = ...' – ZDF

Odpowiedz

8

Kiedy piszesz:

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

wtedy można powiedzieć, że idInt można zawinąć funkcji, zamknięcie .. co może być wywołana z int argument. Ale nie jest to prawdą w przypadku [](int &i) {return i;};, ponieważ nie można nazwać jej integralną dosłowny jak tutaj:

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

można naprawić zmieniając podpis do korzystania rvalue odniesienia lub const &:

std::function<int(int)> idInt1 = [](int &&i) {return i;}; 
std::function<int(int)> idInt2 = [](const int &i) {return i;}; 
Powiązane problemy