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中的调用很罗嗦。原本一行搞定的,现在得多搞好些行给结构体赋值。
7 个解决方案
#1
将F写成一个宏:
#define F(fun) do{prepare(); fun; endwork();}while(0)
否则你
F(f1(a, b));//这里的f1(a,b);是调用函数,而不是作为函数指针传递。
#define F(fun) do{prepare(); fun; endwork();}while(0)
否则你
F(f1(a, b));//这里的f1(a,b);是调用函数,而不是作为函数指针传递。
#2
tr1中的bind
例如VS2008 sp1
例如VS2008 sp1
#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;
}
#3
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;
}
#4
F(fun_ptr)多个重载版本,也很烦。
可以讲参数抽象出来,比如
可以讲参数抽象出来,比如
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;
}
#5
这个最好了
#7
多谢各位,不好意思,一段时间断网了。手机只能看贴,登陆不上。
1楼好像没看懂问题
2楼的确实是好方法,但不幸我用的是vc2005...泪奔
3楼的没有解决根本问题
4楼的方法和我说的那个“不算办法的办法”本质上一样
我的问题已经解决,用va_list解决的,就是类似于printf传参的那种办法。
1楼好像没看懂问题
2楼的确实是好方法,但不幸我用的是vc2005...泪奔
3楼的没有解决根本问题
4楼的方法和我说的那个“不算办法的办法”本质上一样
我的问题已经解决,用va_list解决的,就是类似于printf传参的那种办法。
#1
将F写成一个宏:
#define F(fun) do{prepare(); fun; endwork();}while(0)
否则你
F(f1(a, b));//这里的f1(a,b);是调用函数,而不是作为函数指针传递。
#define F(fun) do{prepare(); fun; endwork();}while(0)
否则你
F(f1(a, b));//这里的f1(a,b);是调用函数,而不是作为函数指针传递。
#2
tr1中的bind
例如VS2008 sp1
例如VS2008 sp1
#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;
}
#3
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;
}
#4
F(fun_ptr)多个重载版本,也很烦。
可以讲参数抽象出来,比如
可以讲参数抽象出来,比如
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;
}
#5
这个最好了
#6
#7
多谢各位,不好意思,一段时间断网了。手机只能看贴,登陆不上。
1楼好像没看懂问题
2楼的确实是好方法,但不幸我用的是vc2005...泪奔
3楼的没有解决根本问题
4楼的方法和我说的那个“不算办法的办法”本质上一样
我的问题已经解决,用va_list解决的,就是类似于printf传参的那种办法。
1楼好像没看懂问题
2楼的确实是好方法,但不幸我用的是vc2005...泪奔
3楼的没有解决根本问题
4楼的方法和我说的那个“不算办法的办法”本质上一样
我的问题已经解决,用va_list解决的,就是类似于printf传参的那种办法。