繁体   English   中英

如何编写一个函数指针,返回一个返回函数指针的函数?

[英]How to write a function pointer to a function returning a function pointer to a function?

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

我想一种简化问题的方法,所以它不会混淆:

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

????? 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来终止程序)mid-loop 似乎是最简单的方法,但我没想到指向数据的指针和指向函数地址的指针与每个指针都不相容其他。 我认为在这种情况下,返回多态函数对象将最终成为更合理的选项。

不要使用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 << "arbitraryFunction\n";
    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的指针应具有与指向字符类型的指针相同的表示和对齐要求。 同样,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。 所有指向结构类型的指针都应具有相同的表示和对齐要求。 所有指向union类型的指针都应具有相同的表示和对齐要求。 指向其他类型的指针不需要具有相同的表示或对齐要求。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM