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

前端 未结 4 657
清酒与你
清酒与你 2020-12-06 04:57

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 nu

相关标签:
4条回答
  • 2020-12-06 05:33

    You want std::function, a polymorphic function object, and std::bind to create function objects by binding arguments to the parameters of other functors.

    If you can't use C++11, then boost::function and boost::bind are equivalent, although slightly more restrictive.

    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()) 
    { ... }
    
    0 讨论(0)
  • 2020-12-06 05:53

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

    Are functoids something I should look at?

    Generally yes, but they don’t solve this problem.

    0 讨论(0)
  • 2020-12-06 05:57

    You could use std::function<> and 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. If you can't use C++11 but can use TR1, replace all std:: with std::tr1::. There is also a Boost implementation.

    0 讨论(0)
  • 2020-12-06 05:57

    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.

    0 讨论(0)
提交回复
热议问题