2010-12-13 9 views
2

Ich habe eine Struktur, die einen Funktionszeiger, wie dies geschieht:Wie erstelle ich eine C-Factory-Funktion?

typedef int (*node_transition_func)(wint_t); 

typedef struct lex_dfa_arc_t { 

    node_transition_func func; 
    int expected_return_val; 
    struct lex_dfa_node_t * node; 

} LEX_DFA_ARC_T; 

Und nun möchte ich eine Funktion erstellen, die eine Funktion des Prototyps gibt „int func (wint_c);“ Zum Beispiel:

node_transition_func input_equals(wint_t input, wint_t desired) { ... } 

Ist es in C möglich, die oben genannte Funktion tatsächlich zu haben? Ich versuche zu vermeiden, eine Funktion für jeden Buchstaben zu definieren (z. B. input_equals_letter_a, input_equals_letter_b, input_equals_letter_c usw.).

Mein anderer Ansatz wäre, nur die node_transition_func in einem wint_t und einem wchar_t * der gewünschten Zeichen zu nehmen, aber ich war neugierig, ob meine erste Annäherung funktionieren würde.

Danke!

+0

Mir war der Begriff Currying bis jetzt nicht bewusst, und ich fand diesen Thread, der eine Menge darüber erklärt: http://stackoverflow.com/questions/1023261/is-there-a-way-to -do-currying-in-c – Scott

Antwort

2

Sie können keine neuen Funktionen in C dynamisch erstellen. Da es sich um eine kompilierte Sprache handelt und der Compiler nicht Teil der Standardlaufzeitumgebung ist, muss der gesamte Code zur Kompilierungszeit statisch definiert sein.

+0

Eigentlich ist das nicht 100% wahr. Sie könnten Ihren eigenen Mini-Compiler kompilierten Code generieren lassen (vielleicht aus vordefinierten Bausteinen kompilierten Codes), ihn irgendwo in den Speicher stecken und ihn dann aufrufen. Abhängig von Kernel-Einschränkungen bei der Verwendung von Speicher natürlich.Wenn Sie jedoch selbst ändernden Code schreiben möchten, ist möglicherweise eine andere Sprache wie LISP besser geeignet. – AlastairG

0

Ich vermute, diese Funktion von Ihnen würde eine Liste von LEX_DFA_ARC_T durchlaufen und das "func" Mitglied eines passenden Elements zurückgeben?

Es gibt keinen Grund, warum das nicht funktionieren sollte. Ein Funktionszeiger wie knotentransitionsfunc ist immer noch nur ein Zeiger. Das ist vielleicht nicht die beste Lösung.

Allerdings bin ich ein wenig verwirrt, ob meine Vermutung richtig ist wegen der anderen Dinge, die Sie sagen. Vielleicht könnte uns ein wenig mehr Kontext helfen, Ihnen zu antworten.

1

Es sieht so aus, als ob Sie versuchen, in C zu curren (cue clippy :-). Ich denke, das ist technisch in C möglich. Sie versuchen nicht, neue Funktionen zu erstellen. Sie versuchen, alternative Bindungen zu einer vorhandenen Funktion zu erstellen. Es ist ziemlich einfach in C++, aber ohne den syntaktischen Zucker, der durch Template-Metaprogrammierung (speziell Funktoren und Bindungen) möglich ist, müssten Sie all diese Dinge manuell erledigen. Ihr anderer Ansatz scheint vernünftiger.

4

Sie könnten grundsätzlich Verschlüsse emulieren & currying von statt "eine Funktion zurückgeben" Sie eine Struktur zurück, die den Funktionszeiger plus die gebundenen Variablen hat. Mit ein paar #defines kann es sogar halbwegs gesund aussehen.

OTOH, wenn Sie eine bestimmte Sprache verwenden, sollten Sie bei seinen Redewendungen bleiben. Closures sind nicht die Stärke von C. Ich schlage vor, dass Sie nicht versuchen, im C-Code übermäßig generisch zu sein, wenn Sie im Zweifelsfall nur einen Schalter() {} verwenden.

0

Dies könnte die nächste sein, Sie zu tun currying in C bekommen können:

int input_equals_with_type(wint_t Input, wint_t desired) { 
     // Do some stuff with regard to different type of "desired" 
     return 1; 
    } 

    #define MAKE_NODE_TRANS_FUNC(type, wint_t desired) \ 
     int node_transition_func_##type(wint_t input) { \ 
      return input_equals_with_type(input, desired); \ 
     } 

    MAKE_NODE_TRANS_FUNC(letter_a, letter_a_disired) 
    MAKE_NODE_TRANS_FUNC(letter_b, letter_b_desired) 
    // and so on... 

Die Einschränkung hier ist natürlich, dass dieser currying nicht „real“ ist, da die Funktionen bei der Kompilierung erstellt werden, nicht ausgeführt Zeit. Aber wenn Sie nur versuchen, ein paar Arten von Funktionen zu machen, dann funktioniert das.