2011-12-21 9 views
13
typedef bool (*Foo)(Foo a, Foo b); 

Come si dichiara un puntatore a funzione che si accetta nei suoi parametri?Un typedef che si riferisce a se stesso

+1

Non si può perché è una definizione ricorsiva senza fine. –

+3

@SethCarnegie: il tuo argomento non è valido. 'struct X {X * a; }; 'è concettualmente lo stesso, ma * è * permesso. – ybungalobill

+1

@ybungalobill: no non lo è, un tipo di funzione contiene i suoi parametri, un tipo di classe non contiene i suoi membri. – Xeo

risposta

8

Indirettamente:

struct Foo{ 
    typedef bool (*FooPtr)(Foo a, Foo b); 
    Foo(FooPtr p) 
     : p(p) 
    {} 

    bool operator()(Foo a, Foo b) const{ 
    return p(a,b); 
    } 

    FooPtr p; 
}; 

struct Bar{ 
    Bar(Foo f) 
     : some_callback(f) 
    {} 

    Foo some_callback; 
}; 

bool a_callback(Foo a, Foo b){ 
    return false; 
} 

int main() { 
    Bar b(a_callback); 
    b.some_callback(Foo(a_callback), Foo(a_callback)); 
} 

Non che io possa mai vedere qualsiasi uso in quanto, come si può vedere dal mio esempio.

+1

Questo non è esattamente quello che è stato chiesto, ma probabilmente è il più lontano possibile. –

+0

Posso fare uso di questo, grazie Xeo. – Tergiver

2

Non è possibile esprimere questo nel sistema di tipi. Anche se non c'è nulla di fondamentalmente sbagliato in questo, semplifica le cose eliminando i cicli all'interno del sistema di tipi. Mi ricorda fortemente lo Axiom of Foundation.

Che cosa si può fare è passare un puntatore nullo e lo gettò al vostro tipo:

typedef bool (*Foo)(void* a, void* b); 

bool f(void* a, void* b) 
{ 
    return ((Foo)a)(a,b); 
} 
+1

Non si possono lanciare puntatori "void *" in puntatori di funzioni come questo. POSIX consiglia di utilizzare qualcosa come 'void * ptr; FunctionPtrType fptr; * (void **) (& fptr) = ptr; ', per evitare comportamenti non definiti. –

+0

@ R.MartinhoFernandes: hai ragione che è stata definita l'implementazione. Ma puoi farlo su qualsiasi sana architettura di von Neumann che abbia "void *" e puntatori di funzione della stessa dimensione. – ybungalobill

+2

Non è possibile eseguire il cast portabile tra "void *" e puntatori di funzioni, indipendentemente dal numero di livelli aggiuntivi di riferimento indiretto aggiunti. Utilizzare invece un altro tipo di puntatore di funzione. –

Problemi correlati