问题描述
|
我如何声明一个指向使用与参数相同的函数指针的函数的函数指针?
我尝试了以下操作但未成功:
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 << \"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);
}
更新:根据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; }
};
,las,这是不可能的。如果可以使用typename
转发声明typedef,那将是很好的。就像是:
typename fnptr;
typedef (*fnptr)(fnptr);
但这是行不通的,因为“ 4”仅限于某些特定的模板用途
,最简单的方法是对两个都进行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);
}