我正试图弄清楚如何能够为具有不同数量的参数的函数分配函数指针。
我有一个while循环,它将许多不同的函数作为一个条件语句,所以不是用内部完全相同的代码编写多个while循环,而是希望有一个带有函数指针的函数。所有函数都是格式bool f(...)
。我认为一些代码最能说明我的意思:
int a, b, c, d;
MyClass* my_class;
typedef bool (MyClass::*my_fun_t)();
my_fun_t my_fun;
if (condition1)
my_fun = &MyClass::function_one();
else if (condition2)
my_fun = &MyClass::function_two(a, b);
else if (condition3)
my_fun = &MyClass::function_three(a, b, c);
else if (condition4)
my_fun = &MyClass::function_four(a, b, c, d);
while ((my_class->*my_fun)())
{ ... }
现在这显然不起作用,因为函数具有不同的签名。是否可以以类似的方式使其工作?我应该看一下functoids吗?
答案 0 :(得分:7)
您可以使用std::function<>
和std::bind()
。
#include <functional>
using std::placeholders::_1;
typedef std::function<bool(MyClass&)> my_fun_t;
my_fun_t my_fun;
if (condition1)
my_fun = std::bind(&MyClass::function_one, _1);
else if (condition2)
my_fun = std::bind(&MyClass::function_two, _1, a, b);
else if (condition3)
my_fun = std::bind(&MyClass::function_three, _1, a, b, c);
else if (condition4)
my_fun = std::bind(&MyClass::function_four, _1, a, b, c, d);
while (my_fun(my_class)) { ... }
这些假设您将使用C ++ 11。如果您不能使用C ++ 11但可以使用TR1,请将所有std::
替换为std::tr1::
。还有Boost implementation。
答案 1 :(得分:4)
这对我有用:
#include <iostream>
#include <cstdarg>
using namespace std;
class MyInterface
{
public:
virtual bool func(int argc, ...) = 0;
};
class MyImpl : public MyInterface
{
public:
virtual bool func(int argc, ...);
};
bool MyImpl::func(int argc, ...)
{
va_list varargs;
va_start(varargs,argc);
cout << "Arguments passed:" << endl;
for(int i = 0; i < argc; ++i)
{
// expect double values
double val = va_arg(varargs,double);
cout << val << endl;
}
va_end(varargs);
return true;
}
typedef bool (MyInterface::*MyFunc)(int, ...);
int main() {
MyImpl impl;
MyInterface* interface = &impl;
MyFunc pfunc = &MyInterface::func;
if(!(interface->*pfunc)(2,double(3.14),double(2.72)))
{
return 1;
}
return 0;
}
输出:
Arguments passed:
3.14
2.72
显然,你可以使用变量参数为(member-)函数声明和使用函数指针。
答案 2 :(得分:3)
您希望std::function
(一个多态函数对象)和std::bind
通过将参数绑定到其他仿函数的参数来创建函数对象。
如果您不能使用C ++ 11,那么boost::function
和boost::bind
是等效的,但限制性稍强。
std::function<bool()> my_fun;
if (condition1)
my_fun = std::bind(&MyClass::function_one, my_class);
else if (condition2)
my_fun = std::bind(&MyClass::function_two, my_class, a, b);
else if (condition3)
my_fun = std::bind(&MyClass::function_three, my_class, a, b, c);
else if (condition4)
my_fun = std::bind(&MyClass::function_four, my_class, a, b, c, d);
while (my_fun())
{ ... }
答案 3 :(得分:1)
我正试图弄清楚如何能够为具有不同数量的参数的函数分配函数指针。
你做不到。函数指针特定于一个函数签名。这完全合乎逻辑:你将如何调用这样的函数? (是的,C允许调用函数而不在其声明中指定函数有多少参数,但这在C ++中不起作用,因为它颠覆了类型系统。)
我应该看一些functoids吗?
一般来说是的,但他们没有解决这个问题。