2013-05-03 11 views
13

Si consideri il seguente funzione che restituisce un lambda:restituendo una lambda senza std :: funzione

std::function<int()> make_counter() 
{ 
    int i = 0; 
    return [=]() mutable { return i++; }; 
} 

E 'possibile restituire il tipo lambda reale, senza avvolgendolo in una std::function?

risposta

18

C++ 11: No. Ogni espressione lambda ha, cito (§5.1.2/3):

[...] un unico, classe non-union senza nome di tipo [ ...]

Ciò significa in effetti che non è possibile conoscere il tipo di lambda senza conoscere prima l'espressione corrispondente.

Ora, se non è stato catturato nulla, è possibile utilizzare la conversione in funzione del puntatore e restituirlo (un tipo di puntatore a funzione), ma è piuttosto limitante.

Come @Luc rilevato nel salotto, se siete disposti a sostituire la make_counter (e se non è un modello, o di sovraccarico, o qualcosa del genere), il seguente avrebbe funzionato:

auto const make_counter = [](int i = 0) { 
    return [i]() mutable { return i++; }; 
}; 

C++ 1y: Sì, tramite deduzione di tipo ritorno per le normali funzioni (N3582).

+1

L'espressione lambda non è valida anche in C++ 11. La deduzione del tipo restituito non funzionerebbe se il corpo contiene più della semplice 'espressione di ritorno; '(§5.1.2,4) –

+0

Tecnicamente è possibile restituire' my_not_STD_function' che semplicemente reimplementa qualcosa di sostanzialmente equivalente ... – Yakk

+1

@Arne: Blame OP per modifica ...: P risolto. – Xeo

10

Se si imbroglia e si utilizza la detrazione di tipo restituito, yes you can (Link).

Nota questo è possibile solo oltre lo stesso C++ 11, sebbene possa essere eseguito in C++ 11 normale e non che avverta l'avviso usando lambdas (ovvero, un lambda all'interno di un lambda che restituisce quella lamba) .

+0

Non C++ 11, non (ancora) standard. – Xeo

+0

Sì, il C++ è ancora lento. = [ –

+0

@Fred vedi di nuovo il link e presta attenzione alla riga di comando usata per compilare. –