具有不同参数的回调函数

时间:2014-03-15 14:20:09

标签: c++ c

我有两个功能稍有不同的功能,所以我不能将它们作为模板功能。

int func64(__int64 a) {
  return (int) a/2; 
} 
int func32(int a) {
    return a--; 
} 

根据变量b64,我想调用func64或func32。我不想在我的代码中多次检查b64是否为真,所以我使用函数指针。

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?

6 个答案:

答案 0 :(得分:2)

传递一个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; 
} 

答案 1 :(得分:2)

该语言要求通过相同函数指针调用的所有函数具有相同的原型。

根据您想要实现的目标,您可以使用已经提到的指针/强制转换方法(在失去类型安全性时满足此要求)或传递工会:

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);                           

}

答案 2 :(得分:0)

首先,请注意函数func32正在返回输入参数

这是因为使用return a--,您会在递减之前返回a 的值。

也许您的意思是return a-1

无论如何,您只需将此功能声明为int func32(__int64 a)

这样,它将具有与函数func64相同的原型,但将与以前完全一样。

顺便说一句,通过指针调用函数可能会更加昂贵"而不是简单的分支操作,因此根据您的应用程序,您可能会使用简单的if / else条件语句更好...

答案 3 :(得分:0)

  

我需要根据标志b64

调用func32()或func64()

这样做:

void do_func(bool b64) {
    if (b64) 
        func64(6);
    else
        func32(6);
} 

答案 4 :(得分:0)

func64制作包装:

int func64_as_32(int a) {
    return func64(a);
}

现在,您可以将func32func64_as_32分配给call_func,因为它们具有相同的签名。您传入的值6的类型为int,因此将其传递给func64_as_32与将其直接传递给func64具有相同的效果。

如果您的呼叫网站传递了__int64类型的值,那么您可以反过来执行此操作,包裹func32

答案 5 :(得分:0)

bool中的C++转换为inttrue => 1false => 0 )您可以使用b64作为数组索引。因此,请参考SJuan76的建议,将函数原型转换为int f(void*)并将它们放入数组int (*array_fun[2])(void* x);。你可以这样调用这些函数:

int p = 6; 
array_fun[b64](&p);