如何编写指向函数的函数指针,返回指向函数的函数指针

How to write a function pointer to a function returning a function pointer to a function?

本文关键字:函数 指针 返回 何编写      更新时间:2023-10-16

我想将函数的地址分配给函数指针,但是要寻址的函数返回与自身具有相同签名的函数指针,导致它以一种我根本无法为函数指针甚至函数声明本身编写返回类型的递归方式…

我想这是一种简化问题的方法,这样就不会让人困惑了:

我怎么能写一个函数声明这样,它可以返回一个指针指向自己(或任何其他函数具有相同的签名)?

????? function(int a){
    // could be this function, or another with the same signature, 
    return arbitraryFunction;  
}
?????(*func)(int) = function;  // same problem as above
编辑:

现在我有一个解决方案,虽然我不会把它作为一个答案,因为它是非常丑陋的。它通过简单地返回一个原始的void*指针作为返回类型来消除递归,并以以下形式结束:

void* function(int parameter){
    return arbitraryFunction; // of the same signature
}
void*(*func)(int) = function; 
func = reinterpret_cast<void*(*)(int)>(func(42));  // sin

edit2:

似乎函数指针和常规指针之间的转换是UB,所以我不能在这种情况下使用void*

回答其中一个评论,这是为了在我的程序中的多个"主"循环之间传递控制,每个循环获得它自己的函数。有很多方法可以做到这一点,但在循环中返回函数指针(或NULL以终止程序)似乎是最简单的方法,但我没有预料到指向数据的指针和指向函数地址的指针会彼此不兼容。我认为在这种情况下,返回多态函数对象将最终成为更合理的选择。

不要使用void*,因为不能保证void *可以保存函数指针。您可以使用void(*)()作为解决方案:

typedef void(*void_func)();
typedef void_func (*func_type) (int);
void_func arbitraryFunction(int a) {
    // could be this function, or another with the same signature, 
    cout << "arbitraryFunctionn";
    return nullptr;  
}
void_func function(int a) {
    // could be this function, or another with the same signature, 
    return (void_func) arbitraryFunction;  
}
int main() {
    // your code goes here
    func_type f = (func_type) function(0);
    f(0);
    return 0;
}

生活

C99 [6.2.5/27]:

指向void的指针应与指向字符类型的指针具有相同的表示和对齐要求。类似地,指向兼容型号的合格或不合格版本应具有相同的表示和对齐要求。所有指向结构类型应具有相同的表示和对齐方式需求彼此一致。所有指向联合类型的指针都应该有彼此具有相同的表示和对齐要求。指针其他类型不需要具有相同的表示或对齐方式要求。

C99 [6.3.2.3/8]:

指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再转换回来;结果要比较等于原来的指针

C中的技巧是利用任何类型的函数指针都可以被强制转换为任何其他类型的函数指针的事实:

#include <stdlib.h>
#include <stdio.h>
typedef void(*emptyfunc)(void);
typedef emptyfunc (*funcptr2)(int);
funcptr2 strategy(int m)
{
  printf("Strategy %d.n", m);
  return (funcptr2)&strategy;
}
int main (void)
{
  const funcptr2 strategy2 = (funcptr2)strategy(1);
  const funcptr2 strategy3 = (funcptr2)strategy2(2);
  strategy3(3);
  return EXIT_SUCCESS;
}

指向策略的每个指针总是属于可调用一次的类型,返回值被放回到可再次调用的形式。

在c++中,可以声明一个函数对象:

class strategy {
  public:
  virtual const strategy& operator()(int) const = 0;
}

可以像调用函数一样调用该类的实例

我怀疑你想做的是一个更复杂的版本,就像这样:

typedef MainLoop *MainLoop(); // not legal
extern MainLoop* main_loop_1();
extern MainLoop* main_loop_2();
MainLoop* main_loop_1()
{
    // do some work here
    return main_loop_2;
}
MainLoop* main_loop_2()
{
    // do some work here
    return main_loop_1;
}
int main()
{
    MainLoop f = main_loop_1;
    for (;;) {
      f = f();
    }
}
一种解决方法是将函数指针包装在结构体中:
struct MainLoop {
    MainLoop (*function_ptr)(); // legal
};
extern MainLoop main_loop_1();
extern MainLoop main_loop_2();
MainLoop main_loop_1()
{
    // do some work here
    return {main_loop_2};
}
MainLoop main_loop_2()
{
    // do some work here
    return {main_loop_1};
}  
int main()
{
    MainLoop f{main_loop_1};
    for (;;) {
       f = f.function_ptr();
    }
}