2016-04-27 11 views
6

Non capisco il motivo per cui il terzo caso è ok (anche se del tipo lambda argomenti è diverso dal tipo std::function sono), mentre il compilatore si lamenta con la quarta:funzione lambda con diverse firme di std :: funzione

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

Perché esiste una conversione da lvalue a rvalue (la cosiddetta "conversione da lvalue a rvalue"), ma non vi è alcuna conversione da rvalue a lvalue. I costruttori di 'std :: function' non si preoccupano delle firme dichiarate, ma solo se l'espressione * call * implicita è valida. –

+2

Perché non utilizzare 'auto'? 'auto idInt = ...' – ZDF

risposta

8

quando si scrive:

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

allora si dice che idInt può avvolgere una funzione, la chiusura, .. che può essere chiamato con int argomento. Ma questo non è vero nel caso di [](int &i) {return i;};, perché non si può chiamare con letterale integrale come qui:

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

si può risolvere il problema cambiando la firma da usare riferimento rvalue o const &:

std::function<int(int)> idInt1 = [](int &&i) {return i;}; 
std::function<int(int)> idInt2 = [](const int &i) {return i;}; 
Problemi correlati