я видел эта ссылка, описывающая пример фиксированной подписи но хотел бы знать, как написать функцию, которая возвращает указатель на функцию, сигнатура которой зависит от аргумента вызывающей функции (если это вообще возможно)?
Пример:
Предположим, у меня есть
typedef void (*func1) (int);
typedef void (*func2) (int, int);
Я хотел бы иметь функцию get_func
который возвращает указатель на один или другой на основе, скажем, значения целочисленного аргумента, например:
get_func1(0)
возвращается func1
;
get_func2(1)
возвращается func2
,
Я не думаю, что вы можете сделать это так.
Вместо этого вы можете захотеть вернуть указатель на функцию, которая struct
указатель как единственный аргумент, и внутри этого struct
у вас есть переменное количество параметров.
typedef void (*func1) (struct MyStruct*);
а затем внутри MyStruct
:
struct MyStruct {
int param;
struct MyStruct* next;
};
Или что-то типа того. Вы можете связать структуры вместе и читать их все как «params».
Я знаю, что здесь я получу много отрицательных отзывов, но если вы хотите что-то, хотите получить это, знать риск и согласиться с этим, вы можете понизить проверки компилятора, чтобы получить то, что вы хотите.
Ниже я покажу вам один способ получить желаемое. Я не рекомендую делать это, но если вы верите, что это именно то, что вы хотите, продолжайте.
#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
понижает проверки компилятора, в основном говоря, что вы несете ответственность за все неправильное, что может произойти
как насчет
#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);
}