簡體   English   中英

具有不同參數的回調函數

[英]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);
}

現在,您可以將func32func64_as_32分配給call_func因為它們具有相同的簽名。 傳遞中,值6 ,具有類型int ,以便將它傳遞給func64_as_32具有直接傳遞到相同的效果func64

如果您在呼叫站點中傳遞了__int64類型的值,則可以采用相反的方法,將func32包裝func32

隨着C++ bool轉換為inttrue => 1false => 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM