1

I want to make an array of known size of class functions. To do so, I've tried using typedef, but it hasn't been working out so far. Also, some functions take no arguments ex. F(), but others do ex. G(int n), and in the typedef, I don't know how to tell it to accept no arguments for some (tried void but it says it is not a type), and to accept arguments for others.

 class myClass
{
    // An array of void functions
    typedef void(myClass::*arrayOfFunctions)();

private:
    arrayOfFunctions array[3] = { &myClass::F, &myClass::G, &myClass::H };

    void F() { do stuff; }
    void G(int n) { do stuff involving n; }
    void H() { do stuff; }
};

What I have tried: I have successfully made an array of void functions in a main with no classes involved which I can call when wanted, so part of the problem seems to be implementing this in a class and using its class functions.

// This works:

typedef void(*arrayOfFunctions)();

void Action1()
{
    // stuff 1
}

void Action2()
{
    // stuff 2
}

void Action3()
{
    //stuff3
}

int main()
{
    arrayOfFunctions functionArray[] = { Action1, Action2, Action3 };

    // Call Action1
    functionArray[0]();

    return 0;
)
4
  • 6
    I am just curious, what do you want to achieve with it? Commented Nov 22, 2019 at 14:49
  • 1
    You can't do this - all array elements must have the same type. (In C++, an empty parameter list means "no arguments". It is equivalent to the parameter list (void) in C.) Commented Nov 22, 2019 at 14:58
  • 1
    // An array of void functions typedef void(myClass::*arrayOfFunctions)(); -- The better way to do this is to have an array of objects with operator() overloaded. Then you could have one function with no parameters, another with 3, another with 1, all with different return types. The "old school" C-style way of using function pointers is limited. Commented Nov 22, 2019 at 15:18
  • "I don't know how to tell it to accept no arguments for some" - How do you know that you should pass arguments to some? Commented Nov 22, 2019 at 15:38

2 Answers 2

0

As was mentioned in comments, it is not possible directly. You cannot store objects of different type in the same array. However, there are ways to achieve what you want. How to get there very much depends on details. Latest when you call the function you need to know how many parameters to pass.

In your example one possibility is to refactor to have only methods with no parameters:

 class myClass {
    using memFun = void(myClass::*)();
    void set_n(int x) { n = x; }
private:
    memFun array[3] = { &myClass::F, &myClass::G, &myClass::H };    
    void F() { do stuff; }
    void G() { do stuff involving n; }
    void H() { do stuff; }
    int n;
};

I changed the name of the alias, because it is just the type of a function pointer not an array. using is easier to read than typedef (it follows the more common x = something style).

When you call the function G the parameter n has to come from somewhere, so instead of passing it directly you can call set_n before iterating the array and call all mehtods without parameter.

Sign up to request clarification or add additional context in comments.

Comments

0

It is not clear how you want to use such an array. If you know an element index at compile time, then you could probably use a std::tuple with template argument deduction. For example:

class my_class {
public:
    template<std::size_t n, class... Args>
    decltype(auto) call_fn(Args&&... args) {
        constexpr auto ptrs = get_fn_pointers();
        return std::invoke(std::get<n>(ptrs), this, std::forward<Args>(args)...);
    }

private:
    static constexpr auto get_fn_pointers() {
        return std::tuple(&my_class::f, &my_class::g, &my_class::h);
    }

    void f() { 
        std::cout << "f()\n"; 
    }

    void g(int n) { 
        std::cout << "g(" << n << ")\n";
    }

    int h() { 
        std::cout << "h() => "; 
        return 9102;
    }
};

int main() {
    my_class c;
    c.call_fn<0>();               // Output: f()
    c.call_fn<1>(2019);           // Output: g(2019)
    std::cout << c.call_fn<2>();  // Output: h() => 9102
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.