2011-05-25 167 views
7

如何声明一个函数指针指向一个函数,该函数采用与参数相同的函数指针?函数指针指向一个函数指针的函数

我已经尝试没有成功如下:

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

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

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

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

这可能吗?

+1

林不知道,它会像努力模板化与自身的东西,你就结束了一个递归声明 – 2011-05-25 17:23:55

+0

我倒认为它不能做。 – 2011-05-25 17:23:57

+2

如何使用泛型声明和显式强制转换? – casablanca 2011-05-25 17:24:48

回答

13

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

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

更新:每克里斯,维特斯,和Johannes的建议作为,这里有一些方便的隐式转换(如香草萨特的GotW #57):

struct Rec; 

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

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

+1用于管理递归问题的优雅方法。 – dusktreader 2011-05-25 17:36:02

+1

如果你喜欢语法 – 2011-05-25 17:45:37

+0

完美的答案,你甚至可以重写'operator()',使它看起来和行为像一个函数(函子)。非常感谢! :D – 2011-05-25 18:04:21

0

最简单的方法就是敲入两者。一个函数指针就像任何其他类型的参数:

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

编辑:乡亲们都指出你的意思是既要为同一类型。在这种情况下,这是不可能的,因为类型是递归的。创建完整的类型规范是不可能的(函数参数的类型从未完全指定,ergo ...)

+2

我认为OP意味着相同类型的论点。 – casablanca 2011-05-25 17:22:24

+0

'OuterFunctionPtr'将不得不采用'OuterFunctionPtr'作为参数。 – 2011-05-25 17:25:30

+0

-1。错误的typedef! – Nawaz 2011-05-25 17:32:06

0

唉,不能这样做。如果你可以使用typename转发声明一个typedef,那将是很好的;是这样的:

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

但是,这并不工作,因为typename仅限于几个特定的​​模板使用

0

有可能以这种方式:

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

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

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

您也可以打败类型系统通过假装该函数采用其他函数指针类型,然后在您将某些内容传递给该函数并在该函数内部获取原始类型时将其转换。

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

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