[英]Callback functions with different arguments
我有兩個功能稍有不同的功能,因此無法將它們作為模板功能。
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
根據變量b64,我想調用func64或func32。 我不想在代碼中多次檢查b64是否為true,所以我使用了指向函數的指針。
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);
}
如何避免此錯誤並將call_func強制轉換為pfunc32或pfunc64?
傳遞一個void指針並將其強制轉換為函數體。
當然,如果使用錯誤的類型,這意味着更少的編譯器控制; 如果調用func64
並將int
傳遞給它,程序將編譯並產生錯誤的結果,而不會給您任何提示。
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
該語言要求通過同一函數指針調用的所有函數具有相同的原型。
根據您要實現的目標,您可以使用已經提到的指針/廣播方法(在失去類型安全性的情況下滿足此要求)或改為通過並集:
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);
}
好吧,首先,請注意函數func32
將返回輸入參數不變。
這是因為與return a--
,你正在返回的值a
遞減之前 。
也許您是想return a-1
?
無論如何,您都可以簡單地將此函數聲明為int func32(__int64 a)
。
這樣,它將具有與func64
函數相同的原型,但將完全像以前一樣工作。
順便說一句,通過指針調用函數可能比簡單的分支操作更“昂貴”,因此根據您的應用程序,使用簡單的if
/ else
條件語句可能會更好。
我需要根據標志b64調用func32()或func64()
這樣做:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
為func64
包裝:
int func64_as_32(int a) {
return func64(a);
}
現在,您可以將func32
或func64_as_32
分配給call_func
因為它們具有相同的簽名。 傳遞中,值6
,具有類型int
,以便將它傳遞給func64_as_32
具有直接傳遞到相同的效果func64
。
如果您在呼叫站點中傳遞了__int64
類型的值,則可以采用相反的方法,將func32
包裝func32
。
隨着C++
bool
轉換為int
( true
=> 1
, false
=> 0
),您可以使用b64
作為數組索引。 因此,請聽SJuan76的建議,將函數原型轉換為int f(void*)
並將其放入數組int (*array_fun[2])(void* x);
。 您可以這樣調用這些函數:
int p = 6;
array_fun[b64](&p);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.