[C] Funktion, die Ihren eigenen Typ als Argument bekommt

Gast #5699204
Lesenswert?
• ▲
▼
Hallo,

ich möchte eine Funktion deklarieren (oder am besten als typedef), die 
als Argumente eine Integer und einen Funktionszeiger auf genau so eine 
Funktion, wie sie selbst eine ist, akzeptiert.
Wenn ich schreibe
1
typedef int Func_t( int, Func_t* );
geht das ja nicht, weil der Typ Func_t noch nicht bekannt ist.

Aber so geht's auch nicht:
1
typedef int Func_t( int, int(*)() );
2

3
testfunc(int i, Func_t *f) {
4
     return 0;
5
}
6
Func_t *funcptr = testfunc;
Hier meckert der Compiler natürlich, dass *funcptr und testfunc nicht 
vom selben Pointer Typ sind.
Ich müsste casten:
1
Func_t *funcptr = (Func_t*)testfunc;
Kann man denn einen Typ basteln, der als (zweites) Argument einen Zeiger 
auf den eigenen Typ nimmt?
Gast #5699212
Lesenswert?
• ▲
▼
Die Lösung für alle abstrusen Probleme in C ist "Das Problem in ein 
struct stecken, schon funktioniert es".
1
#include <stdio.h>
2

3
typedef struct Foo
4
{
5
    void (*call)(struct Foo, int);
6
} Foo;
7

8
void bar(Foo foo, int i)
9
{
10
    if (i <= 0)
11
        return;
12
    printf("%d\n", i);
13
    foo.call(foo, i-1);
14
}
15

16
int main(void)
17
{
18
    bar((Foo){bar}, 7);
19
    return 0;
20
}
Gast #5699213
Lesenswert?
• ▲
▼
Also in C kann man sowas doch mit dem Präprozessor zusammenbauen 
(vorausgesetzt ich hab überhaupt die Frage richtig verstanden):
1
#define tdef(Name, R, ...) \
2
    typedef R(*Name)(__VA_ARGS__, R(*)(__VA_ARGS__))
3
    
4
tdef(Funktion, int, char, int);
5

6

7
int f(char a, int b, int (*c)(char a, int b)) {
8
    return c(a, b);
9
}
10

11
int x(char a, int b) {
12
}
13

14
void y(char a, int b) {
15
}
16

17
int main() {
18
    Funktion fp = f;
19
    
20
    fp(1, 2, x);
21
    fp(1, 2, y);  // Fehler.
22
}
Ich hoffe, ich mach hier keinen Unsinn...

In C++ könnte man das mit einem Template lösen:
1
#include <functional>
2

3
template <typename R, typename... Args>
4
using Funktion = std::function<R (Args..., std::function<R (Args...)>)>; 
5

6
int f(char a, int b, std::function<int (char a, int b)> c) {
7
    return c(a, b);
8
}
9

10
int x(char a, int b) {
11
}
12

13
void y(char a, int b) {
14
}
15

16
int main() {
17
    Funktion<int, char, int> fp = f;
18
    
19
    fp(1, 2, x);
20
    fp(1, 2, y);  // Fehler.
21
}
Gast #5699444
Lesenswert?
• ▲
▼
Tom schrieb:
> "Das Problem in ein
> struct stecken, schon funktioniert es".
Danke!
Das funktioniert, denn da erscheint das zweite "struct Foo" in einem 
anderen Block, wo es schon bekannt ist.

nocheinGast schrieb:
> Also in C kann man sowas doch mit dem Präprozessor zusammenbauen
Hm, ich glaube nicht, denn auch der Präprozessor muss ja Code 
generieren, den der Compiler als gültig ansieht.

nocheinGast schrieb:
> int f(char a, int b, int (*c)(char a, int b)) {
>     return c(a, b);
> }
Auch hier ist ja *c nicht vom selben Typ wie f.
Beitrag #5699472 wurde von einem Moderator gelöscht.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.