2011-06-23 12 views
44

Qual è il modo corretto per definire una funzione che riceve un parametro lambda int->int per riferimento?C++ 0x: modo corretto per ricevere un lambda come parametro per riferimento

void f(std::function< int(int) >& lambda); 

o

void f(auto& lambda); 

non sono sicuro l'ultima forma è anche la sintassi legale.

Esistono altri modi per definire un parametro lambda?

+5

Perché avresti bisogno del lambda come riferimento? Intendi 'const &'? –

risposta

50

Non è possibile avere un parametro auto. Fondamentalmente hai due opzioni:

Opzione 1: usa std::function come hai mostrato.

Opzione # 2: utilizzare un parametro di modello:

template<typename F> 
void f(F &lambda) { /* ... */} 

Opzione # 2 può, in alcuni casi, essere più efficiente, in quanto si può evitare una dotazione potenziale heap per l'oggetto funzione lambda incorporato, ma è possibile solo se f può essere inserito in un'intestazione come una funzione modello. Può anche aumentare i tempi di compilazione e l'impronta di I-cache, come qualsiasi modello. Si noti che potrebbe non avere alcun effetto, come se l'oggetto funzione lambda fosse abbastanza piccolo da poter essere rappresentato in linea nell'oggetto std::function.

+1

I modelli possono anche migliorare l'impronta di I-cache, eliminando i salti al codice generale non locale (in questo caso, eseguire direttamente il lambda, senza dover prima saltare il wrapper 'std :: function' generico) – jalf

+5

Questa citazione , _ "se l'oggetto funzione lambda è abbastanza piccolo può essere rappresentato in linea nell'oggetto' std :: function' "_ è fuorviante. Lambdas è sempre disponibile per inline (il compilatore può scegliere di non farlo ovviamente). Le implementazioni 'std :: function' generalmente usano l'ottimizzazione di piccoli oggetti per evitare allocazioni di heap. Se un lambda ha una lista _capture abbastanza piccola_ essa sarà memorizzata in 'std :: function' senza usare l'heap. A parte il fatto che le dimensioni di un lambda non hanno un significato reale. –

+1

@bdonlan: A proposito, perché c'è '&' in 'void f (F & lambda)'? – Nawaz

23

userei template come:

template<typename Functor> 
void f(Functor functor) 
{ 
    cout << functor(10) << endl; 
} 

int g(int x) 
{ 
    return x * x; 
} 
int main() 
{ 
    auto lambda = [] (int x) { cout << x * 50 << endl; return x * 100; }; 
    f(lambda); //pass lambda 
    f(g);  //pass function 
} 

uscita:

500 
1000 
100 

Demo: http://www.ideone.com/EayVq

0

So che questa domanda è già stato risposto, ma quando ero alla ricerca di una risposta a questa domanda, stavo cercando qualcosa di diverso rispetto alle risposte qui, e penso che questo potrebbe essere stato ciò a cui alludeva l'OP, quindi spero questo aiuterà qualcun altro.

Diciamo che avete una funzione:

void print(int n) 
{ 
    printf("%i ", n); 
} 

per passare un lambda a questa funzione, effettuare le seguenti operazioni:

print([]{ 
    return 3; 
}()); 

Questa passerà 3 alla funzione, ovviamente. Un esempio più utile, in particolare legati alla domanda del PO, è un lambda che prende un intero come parametro e restituisce un int alla funzione fine:

int x = 3; 

auto lambdaFunction = [](int input) { 
    return (input + 1); 
}; 

print(lambdaFunction(x)); 

Ciò presuppone non passa per valore o per riferimento al lambda, che puoi fare direttamente:

// Pass by value 
print([=]{ 
    return (x + 1); 
}()); 

// Pass by reference 
print([&]{ 
    return (x + 1); 
}()); 
+4

Quello che stai facendo non è "passare [ing] un lambda a questa funzione", ma invocando il lambda e passando il suo valore di ritorno alla funzione. Molto diverso da quello che l'OP chiedeva. Potrebbe essere o non essere stato quello che l'OP aveva in mente in origine, ma la sua domanda era chiaramente come accettare un funcda lambda come argomento di funzione. – Kiruse

+0

Ah, ok. Mi sono imbattuto nella domanda di OP mentre cercavo quello che alla fine ho postato, il mio errore –

Problemi correlati