【问题标题】:Return a pointer to function with varying signature based on argument根据参数返回指向具有不同签名的函数的指针
【发布时间】:2013-11-25 07:24:12
【问题描述】:

我见过this link describing a fixed signature example,但想知道如何编写一个函数来返回一个指向函数的指针,该函数的签名取决于调用函数的参数(如果可能的话)?

例子:

假设我有

typedef void (*func1) (int);
typedef void (*func2) (int, int);

我想要一个函数get_func,它根据整数参数的值返回一个指向其中一个或另一个的指针,例如: get_func1(0) 返回func1get_func2(1) 返回func2

【问题讨论】:

  • 您可以返回具有两个不同 operator () 重载的对象。否则不 - 这是一种静态类型的语言。
  • 调用代码如何使用结果?
  • 调用者在尝试调用指向的函数时如何知道有多少参数及其类型?

标签: c++ function-pointers function-signature


【解决方案1】:

怎么样

#include <stdio.h>

typedef void (*func1) (int);
typedef void (*func2) (int, int);

union func12 {
  void* f0;
  func1 f1;  
  func2 f2;
};

void f1(int) {
  printf( "f1\n" );
}

void f2(int, int) {
  printf( "f2\n" );
}

func12 get_func( int x ) {
  func12 r;
  if( x ) r.f2=f2; else r.f1=f1;
  return r;
}

int main() {
  get_func(0).f1(0);
  get_func(1).f2(0,0);
}

http://rextester.com/ZLIXM68236

【讨论】:

    【解决方案2】:

    我知道 Iĺl 在这里得到了很多反对意见,但如果你想要什么,渴望得到它,知道风险并同意它,你可以降低编译器检查以获得你想要的东西。

    下面我将向您展示一种获得所需的方法。我不建议这样做,但如果您认为这正是您想要的,请继续。

    #include <iostream>
    
    using namespace std;
    
    typedef void (*func1) (int);
    typedef void (*func2) (int, int);
    
    void f1(int)
    {
      cout << "f1" << endl;
    }
    
    void f2(int, int)
    {
      cout << "f2" << endl;
    }
    
    void call(int x, void *t)
    {
      if ( x ) 
        reinterpret_cast<func1>(t)(0);
      else
        reinterpret_cast<func2>(t)(0, 0);
    }
    
    int main()
    {
      call(0, reinterpret_cast<void*>(f1));
      call(1, reinterpret_cast<void*>(f2));
    }
    

    如前所述,reinterpret_cast 正在降低编译器检查,基本上是说您对可能发生的所有错误负责

    【讨论】:

    • @Badan:感谢您的回复 - 不过这很有用。
    【解决方案3】:

    我认为你不能那样做。

    您可能想要做的是返回一个指向函数的指针,该函数将一些 struct 指针作为它的唯一参数,并且在该 struct 中,您有可变数量的参数。

    typedef void (*func1) (struct MyStruct*);
    

    然后在MyStruct:

    struct MyStruct {
      int param;
      struct MyStruct* next;
    };
    

    或者类似的东西。您可以将这些结构链接在一起,并将它们全部读取为“参数”。

    【讨论】:

    • @Haole:我也怀疑过,你可能是对的。我得再考虑一下。但最终可能会做你建议的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2013-05-22
    • 1970-01-01
    • 2018-02-05
    • 2020-07-03
    • 2013-04-10
    • 2017-03-26
    相关资源
    最近更新 更多