Home > Software engineering >  How can I call a function from an array of functions via its index?
How can I call a function from an array of functions via its index?

Time:12-16

A beginner's question I couldn't find answered online, likely because I don't know the terminology.

I want to call one of a list of procedures based on a computed index value. That is, given a '1', invoke firstProc(), '2' invokes secondProc() and so on.

All the procedures are void functions with no arguments.

I can implement that with switch/case, but what I'd prefer is something like:

void* action[2] {*firstProc, *secondProc};

(This compiles, but warns: invalid conversion from 'void (*)()' to 'void*')

and then later:

action[get_index()]();

The compiler objects that 'action' can't be used as a function.

This must be possible, right? I've tried several variations but I can't get past the use of the selected ('action[index]') as a function.

CodePudding user response:

There are two equivalent ways to do what you want. The explanation is given as comments in the code snippets.

Method 1


#include <iostream>
void foo() 
{ 
    std::cout << "Hello";
}
void foo2() 
{ 
    std::cout << " wolrd!"; 
    
}


int main()
{
   
    void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything
    
    void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything
    
    
    //create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter
    void (*arr[2])() = { a, b};
    
    arr[0](); // calls foo 
    
    arr[1](); //calls foo1
    
    return 0;
}

Method 1 can be executed here.

In method 1 above void (*a)() = foo; means that a is a pointer to a function that takes no parameter and also does not return anything.

Similarly, void (*b)() = foo2; means that b is a pointer to a function that takes no parameter and also does not return anything.

Next, void (*arr[2])() = { a, b}; means that arr is an array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter.

Method 2


#include <iostream>
void foo() 
{ 
    std::cout << "Hello";
}
void foo2() 
{ 
    std::cout << " wolrd!"; 
    
}


int main()
{
   
    //create array(of size 2) that can hold pointers to functions that does not return anything
    void (*arr[2])() = { foo, foo2};
    
    arr[0](); // calls foo 
    
    arr[1](); //calls foo1
    
    return 0;
}

Method 2 can be executed here.

CodePudding user response:

You need the correct syntax for your function pointer array. void(*func_ptr[])().

Example:

void func1() { std::cout << "Hallo" << std::endl; }
void func2() { std::cout << "World" << std::endl; }

// if you need a different signature for your functions like:
int func3(int n) { std::cout << "n1 " << n << std::endl; return n*2; }
int func4(int n) { std::cout << "n2 " << n << std::endl; return n*3; }

int main()
{
    // array of function pointer which
    // have no parameter and void as return value
    void(*func_ptr[])()={ func1, func2 };

    for ( unsigned int idx = 0; idx<2; idx   )
    {
        func_ptr[idx]();
    }

    // array of function pointers with int return value and int as
    // parameter
    int(*func_ptr2[])(int)={ func3, func4 };

    for ( unsigned int idx = 0; idx<2; idx   )
    {
        std::cout << "retval: " << func_ptr2[idx](6) << std::endl;
    }
}

CodePudding user response:

I've stopped using function pointers (though they still can be useful). I usually use std::function (and lambdas) when working with functions

Code for arrays of functions then look like this. I used std::vector but std::array for fixed size should work fine too.

#include <vector>
#include <functional>
#include <iostream>

void some_function()
{
    std::cout << "some function\n";
}

int main()
{
    // std::function, abstraction of a function, function signature = template parameter, so void () is  function returning a void, no parameters
    // std::vector, runtime resizable array
    // constructor : 4 time a lambda function printing out hello world.
    std::vector<std::function<void()>> functions(4, [] { std::cout << "Hello World!\n"; } );

    // easy syntax to assign an existing function to an index
    functions[1] = some_function;
    
    // replace a function in the vector with another one (lambda)
    functions[2] = [] { std::cout << "booh\n"; };

    // call function at index 0
    functions[0]();
    std::cout << "\n\n";

    // or loop over all the functions and call them (classic for loop)
    for (std::size_t n = 0; n < functions.size();   n) functions[n]();
    std::cout << "\n\n";

    // or loop over all the functions (range based for loop)
    for (const auto& function : functions) function();

    return 0;
}
  • Related