Function pointer pointing to a function that takes a function pointer

雨燕双飞 提交于 2019-11-28 00:41:33

问题


How do I declare a function pointer that points to a function taking the same function pointer as the argument?

I've tried the following without success:

typedef void (*fnptr)(void (*)());

void func(fnptr)
{
    /* ... */
}

void func2(fnptr)
{
    /* ... */
}

void main()
{
    fnptr fn = &func;
    func2(fn);
}

Is this possible?


回答1:


I very much doubt it, but you can get the needed recursion by introducing a struct.

struct Rec;

typedef void (*RecFun)(const Rec&);

struct Rec {
    RecFun fun;
};

Example of use:

#include <iostream>

void nothing(const Rec& rec) {}
Rec recNothing = { nothing };

void f(const Rec& rec)
{
    std::cout << "f\n";
    rec.fun(recNothing);
}
Rec recF = { f };

void g(const Rec& rec)
{
    std::cout << "g\n";
    rec.fun(recNothing);
}
Rec recG = { g };

int main()
{
    recF.fun(recG);
}

Update: As per the suggestions of Chris, Vitus, and Johannes, here are some convenient implicit conversions (as in Herb Sutter's GotW #57):

struct Rec;

typedef void (*RecFun)(const Rec&);

struct Rec {
    RecFun fun;
    Rec(RecFun fun) : fun(fun) {}
    operator RecFun() const { return fun; }
};



回答2:


Alas, it cannot be done. It would be nice if you could use typename to forward declare a typedef; something like:

typename fnptr;
typedef (*fnptr)(fnptr);

but that does not work, because typename is restricted to a few specific template uses




回答3:


The easiest way is to just typedef both. A function pointer is a parameter just like any other type:

typedef (* InnerFunctionPtr)(void);
typedef (* OuterFunctionPtr)(InnerFunctionPtr);

Edit: Folks have pointed out you mean both to be the same type. In that case, it's not possible, as the type would be recursive. It's impossible to create a complete type specification (the type of the function's parameter is never completely specified, ergo...)




回答4:


it is possible in this way:

typedef void (*fnptr)(void (*)());

fnptr fn1,fn2;
void func(fn1)
{
/* ... */
}

void func2(fn2)
{
/* ... */
}
void main()
{
fnptr fn = &func;
func2(fn);
}



回答5:


You can also defeat the type system by pretending that the function takes some other function pointer type, and then casting it when you pass something to the function and inside the function to get the original type back.

Not recommended obviously, but just putting it out there.

typedef void (*fnptr)(void (*)());

void func(void (*x)())
{
    fnptr f = (fnptr)x;
    /* ... */
}

void func2(void (*x)())
{
    fnptr f = (fnptr)x;
    /* ... */
}

void main()
{
    fnptr fn = &func;
    func2((void (*)())fn);
}


来源:https://stackoverflow.com/questions/6128344/function-pointer-pointing-to-a-function-that-takes-a-function-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!