2013-02-25 7 views
6

Boost Lambda/Phoenix supporta fuori dalla scatola qualcosa come lambda che restituisce un altro lambda?Boost Lambda/Phoenix - come fare lambda che restituisce un altro lambda?

Per esempio, che può essere usato per fare una sorta di currying:

std::cout << [](int x){return [=](int y){return x+y;};}(1)(2); 

Come realizzare scopo simile con Boost Lambda/Phoenix (+ come un bonus - che avremmo avuto un comportamento polimorfico)?

+0

Il problema che ho avuto nel tentativo di rispondere a questa è che 'arg1' viene consumato dal più esterno' bind' - Voglio un 'arg1' Posso passare al' bind interno ', ma il 'bind esterno' lo mangia invece. Se avessi un modo per "sfuggire" all'argomento segnaposto ... – Yakk

+0

@Yakk, potresti provare a usare boost :: bind - AFAIK si differenzia da lambda/phoenix bind (http://www.boost.org/doc/ libs/1_53_0/doc/html/lambda/s08.html # idp111396608). Inoltre, il codice postale del tuo tentativo come risposta - bounty termina domani ... – qble

risposta

5

Boost Phoenix Scope: let/lambda

Live demo:

#include <boost/phoenix.hpp> 
#include <iostream> 
#include <ostream> 

using namespace std; 
using namespace boost; 
using namespace phoenix; 
using namespace arg_names; 
using namespace local_names; 

int main() 
{ 
    // capture by reference: 
    cout << 
     (lambda(_a=_1)[_1 + _a ])(1)(2) 
    << endl; 
    cout << 
     (lambda(_b=_1)[lambda(_a=_1)[_1 + _a + _b ]])(1)(2)(3) 
    << endl; 
    // capture by value: 
    cout << 
     (lambda(_a=val(_1))[_1 + _a ])(1)(2) 
    << endl; 
    cout << 
     (lambda(_b=val(_1))[lambda(_a=val(_1))[_1 + _a + _b ]])(1)(2)(3) 
    << endl; 
} 

uscita è:

3 
6 
3 
6 
+0

Questo è quello che sto cercando, grazie! – qble

+0

@EvgenyPanasyuk c'è un modo semplice per generare una valutazione lazy, come '[&]() -> void {fully_bound_expression_that_does_not_run_until_later; } '? – Yakk

+0

@Yakk, Potrebbe descrivere in dettaglio cosa intendi (magari tramite un esempio completo con C++ 11 lambda)? Intendi http://liveworkspace.org/code/30jCv6$0? O forse http://liveworkspace.org/code/2Kon3g$0? –