2013-03-11 11 views
6

C'è un modo per creare un typedef tale che la seguente (un'implementazione "pura" di base del combinatore y) venga compilata?Typedef per lambda ricorsiva

typedef ??? f; 
[](f x){x(x);} ([](f x){x(x);}); 

Questo ha l'effetto di creare un "lambda ricorsivo", cioè uno che si definisce utilizzando un secondo lambda per ottenere un riferimento a se stessa. x nel primo lambda è un riferimento al secondo lambda, quindi x(x) chiama il secondo lambda con un riferimento a se stesso. Successivamente, la seconda lambda ricorre chiamando x(x). Questo codice, quando viene eseguito, dovrebbe produrre un ciclo infinito fino a quando non raggiunge l'overflow dello stack. Implementazioni più sofisticate della seconda funzione possono produrre un comportamento ricorsivo arbitrario.

Ho provato typedef varie versioni di void(*)(...) ma non credo che possa riuscire. La metaprogrammazione del mio modello non è abbastanza forte per gestire questo tipo di cose.

+0

Che cosa fa x (x); supponiamo di fare (supponendo che sia possibile)? Inoltre, cosa significa l'argomento '([] (f x) {x (x);})' e lo fa? Dacci qualche idea su cosa stai facendo. – Nawaz

+0

Recurse just. È un y-combinator. – nneonneo

+0

@nneonneo: OK, non so che cos'è un combinatore y, quindi credo che la mia risposta sembri idiota. Questo dovrebbe semplicemente creare una ricorsione infinita chiamandosi? E ti è permesso definire una nuova classe 'X', e quindi' typedef X f'? –

risposta

6

Che ne dici di questo?

#include <functional> 
#include <iostream> 

struct X 
{ 
    template<typename F> 
    X(F f) : _f(f) 
    { } 

    void operator() (std::function<void(X)> f) 
    { 
     std::cout << "Calling myself..." << std::endl; 
     _f(f); 
    } 

    std::function<void(X)> _f; 
}; 

int main() 
{ 
    typedef X f; 
    [](f x){x(x);} ([](f x){x(x);}); 
} 
+0

Hm. Bene, soddisfa la lettera della legge, se non lo spirito (il secondo lambda è fondamentalmente inutilizzato). – nneonneo

+0

@nneonneo: intendi il primo. – Xeo

+0

@Xeo: Hm? Il primo lambda costruisce un 'f x' usando il secondo lambda, quindi chiama' x (x) '. Ma il secondo lambda viene buttato via dopo essere stato usato per la costruzione. – nneonneo