简体   繁体   English

C ++:函数指向具有可变数量参数的函数

[英]C++: Function pointer to functions with variable number of arguments

I'm trying to figure out a way of how to be able to assign a function pointer to functions with different number of arguments. 我试图找出一种方法,如何能够为具有不同数量的参数的函数分配函数指针。

I have a while loop which takes a number of different functions as a conditional statement, so instead of writing multiple while loops with exactly the same code inside I'd like to have one with a function pointer. 我有一个while循环,它将许多不同的函数作为一个条件语句,所以我没有用完全相同的代码编写多个while循环,而是希望有一个带有函数指针的函数。 All the functions are of format bool f(...) . 所有函数都是bool f(...)格式。 I think some code will best illustrate what I mean: 我认为一些代码最能说明我的意思:

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)()) 
{ ... }

Now this obviously doesn't work because the functions have different signatures. 现在这显然不起作用,因为函数具有不同的签名。 Is it at all possible to make it work in a similar fashion? 是否可以以类似的方式使其工作? Are functoids something I should look at? 我应该看一下functoids吗?

You could use std::function<> and std::bind() . 您可以使用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)) { ... }

These assumes you will use C++11. 这些假设您将使用C ++ 11。 If you can't use C++11 but can use TR1, replace all std:: with std::tr1:: . 如果您不能使用C ++ 11但可以使用TR1,请将所有std::替换为std::tr1:: There is also a Boost implementation . 还有一个Boost实现

This works for me: 这对我有用:

#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;
}

Output: 输出:

Arguments passed:
3.14
2.72

Obviously you CAN declare and use function pointers for (member-)functions using variable arguments. 显然,您可以使用变量参数为(member-)函数声明和使用函数指针。

You want std::function , a polymorphic function object, and std::bind to create function objects by binding arguments to the parameters of other functors. 您希望std::function ,一个多态函数对象和std::bind通过将参数绑定到其他仿函数的参数来创建函数对象。

If you can't use C++11, then boost::function and boost::bind are equivalent, although slightly more restrictive. 如果你不能使用C ++ 11,那么boost::functionboost::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()) 
{ ... }

I'm trying to figure out a way of how to be able to assign a function pointer to functions with different number of arguments. 我试图找出一种方法,如何能够为具有不同数量的参数的函数分配函数指针。

You can't. 你不能。 Function pointers are specific to one function signature. 函数指针特定于一个函数签名。 This is entirely logical: how would you invoke such a function? 这完全合乎逻辑:你将如何调用这样的函数? (Yes, C allows invoking functions without specifying in their declaration how many parameters the function has, but this doesn't work in C++ since it subverts the type system.) (是的,C允许调用函数而不在其声明中指定函数有多少参数,但这在C ++中不起作用,因为它颠覆了类型系统。)

Are functoids something I should look at? 我应该看一下functoids吗?

Generally yes, but they don't solve this problem. 一般是的,但他们没有解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM