指向采用函数指针的函数的函数指针

Function pointer pointing to a function that takes a function pointer

本文关键字:函数 指针      更新时间:2023-10-16

如何声明一个函数指针,该指针指向以相同函数指针作为参数的函数?

我尝试了以下操作,但没有成功:

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

这可能吗?

我非常怀疑它,但您可以通过引入结构来获得所需的递归。

struct Rec;
typedef void (*RecFun)(const Rec&);
struct Rec {
    RecFun fun;
};

使用示例:

#include <iostream>
void nothing(const Rec& rec) {}
Rec recNothing = { nothing };
void f(const Rec& rec)
{
    std::cout << "fn";
    rec.fun(recNothing);
}
Rec recF = { f };
void g(const Rec& rec)
{
    std::cout << "gn";
    rec.fun(recNothing);
}
Rec recG = { g };
int main()
{
    recF.fun(recG);
}

更新:根据Chris、Vitus和Johannes的建议,这里有一些方便的隐式转换(如Herb Sutter的GotW#57):

struct Rec;
typedef void (*RecFun)(const Rec&);
struct Rec {
    RecFun fun;
    Rec(RecFun fun) : fun(fun) {}
    operator RecFun() const { return fun; }
};

唉,这是做不到的。如果您可以使用typename来转发声明一个typedef,那就太好了;类似于:

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

但这不起作用,因为typename仅限于少数特定模板使用

最简单的方法是对两者都进行typedef。函数指针是一个参数,就像任何其他类型一样:

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

编辑:人们指出,你的意思是两者都是同一类型。在这种情况下,这是不可能的,因为类型是递归的。创建一个完整的类型规范是不可能的(函数参数的类型从来没有完全指定,呃…)

通过这种方式是可能的:

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

您还可以通过假装函数采用其他函数指针类型来击败类型系统,然后在向函数传递内容并在函数内部进行强制转换以获取原始类型。

显然不推荐,但只是把它放在那里。

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);
}