[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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren