I have two functions with a little different functionality, so I can't make them as template functions.
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
Depending on variable b64, I would like to call func64 or func32. I don't want check if b64 is true many times in my code, so I use pointers to functions.
void do_func(bool b64) {
typedef int (*pfunc32)(int);
typedef int (*pfunc64)(__int64);
pfunc32 call_func;
if (b64)
call_func = func64; //error C2440: '=' : cannot convert from 'int (__cdecl *)(__int64)' to 'pfunc32'
else
call_func = func32;
//...
call_func(6);
}
How can I avoid this error and cast call_func to pfunc32 or pfunc64?
Pass a void pointer and cast it in the function body.
Of course this means less compiler control if you use the wrong type; if you call func64
and pass an int
to it the program will compile and produce wrong results without giving you any tip of what is going wrong.
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
The language requires all functions called through the same function pointer to have the same prototype.
Depending on what you want to achieve, you could use the pointer/cast aproach already mentioned (which satisfies this requirement at the loss of type safety) or pass a union instead:
union u32_64
{
__int64 i64;
int i32;
};
int func64(union u32_64 a) {
return (int) a.i64/2;
}
int func32(union u32_64 a) {
return --a.i32;
}
void do_func(bool b64) {
typedef int (*pfunc)(union u32_64);
pfunc call_func;
if (b64)
call_func = func64;
else
call_func = func32;
//...
union u32_64 u = { .i64 = 6 };
call_func(u);
}
Well, first of all, please note that function func32
is returning the input argument as is .
This is because with return a--
, you are returning the value of a
before decrementing it.
Perhaps you meant to return a-1
instead?
In any case, you can simply declare this function as int func32(__int64 a)
.
This way, it will have the same prototype as function func64
, but will work exactly as before.
BTW, calling a function through a pointer might be more "expensive" than a simple branch operation, so depending on your application, you might be better off with a simple if
/ else
conditional statement...
I need to call func32() or func64() depending on flag b64
So do that:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
Make a wrapper for func64
:
int func64_as_32(int a) {
return func64(a);
}
Now you can assign either func32
or func64_as_32
to call_func
since they have the same signature. The value you pass in, 6
, has type int
so passing it to func64_as_32
has the same effect as passing it directly to func64
.
If you have call sites where you pass in a value of type __int64
then you'd do it the other way around, wrap func32
.
As bool
in C++
converts to int
( true
=> 1
, false
=> 0
) you can use b64
as array index. So take SJuan76's advice, convert your functions prototype to int f(void*)
and put them into array int (*array_fun[2])(void* x);
. You can call these functions then like that :
int p = 6;
array_fun[b64](&p);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.