函数指针作为函数参数有关问题

请教高手函数指针作为函数参数问题
RT


void F(函数指针)
{
//准备工作
prepare();

//执行
f1();//(或是f2(),f3()等)

//结束工作
endwork();
}

void f1(int a, int b)

void f2(flot a, flot b, flot c)

void f3(char * a, bool b)

void f3(class_a a)
...

main()
{//任务1
 F(f1(a, b));
 //任务2
 F(f2(a,b,c));
}

F的任务分成三步:准备、执行和结束。准备和结束对所有的任务都是相同的,执行部分则根据任务不同而不同。关键问题是不同任务对应的fi()的参数列表可能很不一样。这时候应该怎么实现呢?如果用模版实现也行。

我自己有一个不算办法的办法,就是在F里面搞一个struct_parameter结构体,所有功能函数fi()都搞成无参数,main中调用时先对结构体中的变量赋值,然后再F(fi())这么用。不过这会使得在main中的调用很罗嗦。原本一行搞定的,现在得多搞好些行给结构体赋值。


------解决方案--------------------
tr1中的bind

例如VS2008 sp1
C/C++ code


#include<functional>
using namespace std;
using namespace tr1;

void Func( function<void()> f)
{
    //准备工作
    //prepare();

    f();
    //结束工作
    //endwork();    
}

void f1(int a, int b);
void f2(float a, float b, float c);
void f3(char * a, bool b);

int main( int argc, char* argv[] )
{
    Func( bind( f1 , 1,2) );
    Func( bind( f2 , 1.0f,2.0f,3.0f) );
    char* p = 0;
    Func( bind( f3 , p,true) );
    return 0;
}

------解决方案--------------------
C/C++ code

void f1()
{
    cout<<"Show()"<<endl;
}
void f2(int a, int b)
{
    cout<<"a + b = "<<a + b<<endl;
}
void f3(char* ch)
{
    cout<<ch<<endl;
}
typedef void (*Pf1)(void);
typedef void (*Pf2)(int a, int b);
typedef void (*Pf3)(char *ch);
union FunPtr
{
    Pf1 fun1;
    Pf2 fun2;
    Pf3 fun3;
};
int main(int argc, char* argv[])
{
    int a = 3;
    int b = 4;
    char* str = "Hello World!";

    FunPtr fun;

    fun.fun1 = (Pf1)f1;
    fun.fun1();

    fun.fun1 = (Pf1)f2;
    fun.fun2(a, b);

    fun.fun1 = (Pf1)f3;
    fun.fun3(str);
    system("pause");
    return 0;
}

------解决方案--------------------
F(fun_ptr)多个重载版本,也很烦。
可以讲参数抽象出来,比如
C/C++ code

enum EArgType
{
    eTypeOne;
    eTypeTwo;
    // ...
};

struct ArgBase
{
    // ...
    EArgType _type; // 类型主要用来static_cast成对应的派生参数
};

struct ArgMore : public ArgBase
{
    // ...
};

typedef void (* PTR_FUN)( const ArgBase & arg );

void fun_a(const ArgBase & arg)
{
    ArgMore arg_more = static_cast<const ArgMore&>(arg);
    arg_more;
    // ... 
}

void Fun( PTR_FUN fun, const ArgBase & arg )
{
    // step one
    // ...

    // step two
    fun(arg);

    // ...
}

int main()
{
    ArgMore arg;
    // 填充arg
    Fun(fun_a, arg);

    // ...

    return 0;
}