How do I create an array of function pointers of different prototypes?

array of function pointers with different parameters
array of function pointers c
array of function pointers c++
array of functions in c
passing array to function in c using pointer
function pointer in c pdf
passing pointers to functions in c
c function pointer typedef

I have a few functions defined like this:

ParentClass*    fun1();
ParentClass*    fun2();
ParentClass*    fun3(bool inp=false);
ChildClass*     fun4();
ChildClass*     fun5(int a=1, int b=3);

I would like to put them into an array of some kind as follows:

void* (*arr[5])() = {
    (void* (*)())fun1,
    (void* (*)())fun2,
    (void* (*)())fun3,
    (void* (*)())fun4,
    (void* (*)())fun5
}

Now I would like to use this array of functions simply as

for(int i=0; i<5; i++)
    someFunction(arr[i]());

Now I realize here that the issue is void* (*arr[5])(), but given that I only want to use the functions without supplying an argument, I would like all of these to be part of the same array.

These are very C-style ways to do it, though. Is there a better way to do it using Templates in C++?

C-style or not, what you have is straight undefined behaviour. Use lambdas:

void (*arr[5])() = {
    [] { fun1(); },
    [] { fun2(); },
    [] { fun3(); },
    [] { fun4(); },
    [] { fun5(); }
};

These are okay because they perform the call through the function's correct type, and are themselves convertible to void (*)().

Forwarding the returned value stays simple enough, since the lambda provides a context for the conversion. In your case, since ChildClass supposedly inherits from ParentClass, an implicit conversion is enough:

ParentClass *(*arr[5])() = {
    []() -> ParentClass * { return fun1(); },
    []() -> ParentClass * { return fun2(); },
    []() -> ParentClass * { return fun3(); },
    []() -> ParentClass * { return fun4(); },
    []() -> ParentClass * { return fun5(); }
};

Function Pointers - How to play with pointers in C, To store the address of this function in a function pointer, following syntax is used: Sometimes there are multiple similar (same prototype) functions to call and a decision must We declare a database (simply an array will work for us) of students and This function takes two pointers to objects to compare with each other. Also, we declare an array of four function pointer. Each function pointer of array element takes two integers parameters and returns an integer value. We assign and initialize each array element with the function already declared. For example, the third element which is the third function pointer will point to multiplication operation function.

but given that I only want to use the functions without supplying an argument

It simply doesn't work like that. Did you ever wonder, then when you're put function declarations in a header, why you have to write default parameters into the header and can not place it in the definition in the implementation source file?

That's because the default parameters are in fact not "embedded" into the function, but used by the compiler to augment a function call with those parameters at a calling location, where those parameters are omitted. (EDIT: Also, as @Aconcagua so keenly observed in a comment, since default parameters are usually defined as part of a header function declaration, any change of the default values requires a full recompilation of any compilation unit that included those headers, ergo function declarations, for the change to actually take effect!)

While it's perfectly possible to do some really weird type casting madness to construct an array of function pointers like that, eventually you'll have to cast back to the original function call signature in order to not invoke undefined behavior.

If anything you'll have to bind the function pointer, together with a set of default parameters in some type that abstracts away the calling, does supply the parameters and to the outside offers a polymorphic interface. So you'd have a std::vector<function_binder> or function_binder[] where function binder has a operator() that calls the function.

But when you're doing binding in the first place, you can bind it in an anonymous function, i.e. lambdas. At the time of lambda instanciation the default parameters are bound.

std::vector<void(*)()> fvec = {
    []{ func0(); },
    []{ func1(); },
    []{ func2(); },
}

How to Create Jump Tables via Function Pointer Arrays in C, Here's a look at the use of arrays of function pointers in C/C++ as jump tables. #define N_SCREENS 16 #define N_KEYS 6 /* Prototypes for There are two syntactically different ways of invoking a function via a pointer. 24.3 Function Pointers and Prototypes. It's generally a good idea to have a function prototype in scope whenever you call a function. Function prototypes allow the compiler to generate correct code for function calls, and to verify that you've called a function with the correct number and type of arguments.

You can use std::bind

std::function<ParentClass *(void)> arr[5] = {
    std::bind(&fun1),
    std::bind(&fun2),
    std::bind(&fun3, false),
    std::bind(&fun4),
    std::bind(&fun5, 1, 3)
};

now you can do

for(int i=0; i<5; i++)
    arr[i]();

You have to make sure every function parameter of all functions are bound.

This also works well with member functions. You just have to bind the object reference (e.g. this) as first parameter.

Function Pointer in C, How to declare a pointer to a function? Following are some 4) Like normal pointers, we can have an array of function pointers. For example, in below program, user is asked for a choice between 0 and 2 to do different tasks. filter_none. Function pointers are an interesting and powerful tool but their syntax can be a little confusing. This post will going into C function pointers from the basics to simple usage to some quirks about function names and addresses. In the end it will give you an easy way to think about function pointers so their usage is more clear.

A c++20 solution:

#define RETURNS(...) \
  noexcept(noexcept(__VA_ARGS__)) \
  -> decltype(__VA_ARGS__) \
  { return __VA_ARGS__; }


template<auto f, class R, class...Args>
struct explicit_function_caster {
  using Sig=R(Args...);
  using pSig=Sig*;
  constexpr operator pSig()const {
    return [](Args...args)->R {
      return static_cast<R>(f(std::forward<Args>(args)...));
    };
  }
};

template<auto f>
struct overload_storer_t {
  template<class R, class...Args>
  constexpr (*operator R() const)(Args...) const {
    return explicit_function_caster<f, R, Args...>{};
  }
  template<class...Args>
  auto operator()(Args&&...args)
  RETURNS( f( std::forward<Args>(args)... ) )
};
template<auto f>
overload_storer_t<f> generate_overloads={};

#define OVERLOADS_OF(...) \
  generate_overloads< \
    [](auto&&...args) \
    RETURNS( __VA_ARGS__( decltype(args)(args)... ) ) \
  >

which is a lot of boilerplate, but gets us:

ParentClass* (*arr[5])() = {
  OVERLOADS_OF(fun1),
  OVERLOADS_OF(fun2),
  OVERLOADS_OF(fun3),
  OVERLOADS_OF(fun4),
  OVERLOADS_OF(fun5)
};
void (*arr2[5])() = {
  OVERLOADS_OF(fun1),
  OVERLOADS_OF(fun2),
  OVERLOADS_OF(fun3),
  OVERLOADS_OF(fun4),
  OVERLOADS_OF(fun5)
};

basically generate_overloads<x> takes a constexpr callable object x and lets you cast it at compile time to a pointer to a function of any compatible signature and call it with (almost) any signature.

Meanwhile, OVERLOADS_OF converts a function name into a constexpr object that does overload resolution on that function name. I use it here because fun3 as a function pointer does not know about its default arguments, but at overload resolution time it does.

In this particular case, it is far easier to just write toy lambdas to do this work; this is just an attempt to automate writing those toy lambdas for arbitrary compatible signatures.

Functions Pointers in C Programming with Examples, We declare and define add_array() function which takes an array address( pointer) with its elements number as parameters and returns the  A function pointer is a variable that stores the address of a function that can later be called through that function pointer. This is useful because functions encapsulate behavior. For instance, every time you need a particular behavior such as drawing a line, instead of writing out a bunch of code, all you need to do is call the function.

Since you have tagged question with C++14 you should not use function pointers!

With C++14 you should prefer std::function and lambdas.

Also you should not use C style array, but only std::array and/or std::vector.

Also avoid raw pointers, use std::unique_ptr and std::shared_ptr.

So simplest and best way to solve it is:

std::array<std::function<ParentClass*()>,5> arr {
    []() { return fun1(); },
    []() { return fun2(); },
    []() { return fun3(true); },
    []() { return fun4(); },
    []() { return fun5(7, 9); }
};

Why not simple array of pointers like in @Quentin answer? He used lambdas, but he can't use lambda which binds anything (if you need to).

Function Pointers in C and C++, But sometimes you would like to choose different behaviors at different times in Another use for function pointers is setting up "listener" or "callback" functions that Because we don't know the size of the individual elements in a void* array,  Two ways to do this. Function pointers The oldschool "C" way to do it is with an array of functions. When make a function named "foo", you are creating a name, an identifier. That identifier has a type - it's type is 'pointer to function'. You can assign the value of foo to a variable of the same type.

7.8, Consider a case where you are writing a function to perform a task (such as sorting an array), but you want the user to be able to define how a particular part of that  The only reason for passing an array explicitly by reference is so that you can change the pointer to point to a different array. Constant arrays If a function only looks at the contents of an array, and does not change what is in the array, you usually indicates that by adding const to the parameter.

Basics of Function Pointers in C, This is no different than declaring an int pointer or a char pointer. We must have parentheses around the pointer (*sayHelloPrt) . If we don't have  It is now considered good form to use function prototypes for all functions in your program. A prototype declares the function name, its parameters, and its return type to the rest of the program prior to the function's actual declaration. To understand why function prototypes are useful, enter the following code and run it:

[PDF] Arrays of Pointers to Functions, 05/99, LISTING 1 A two-dimensional array of function pointers is often used in keypad applications. #define N_SCREENS. 16. #define N_KEYS. 6. /* Function prototypes  The scope of the function prototype in C is determined by its position in the program. Generally, the function prototype is placed after the header file in the program. The scope of the function prototype is considered within the same block as the function call. Another interesting feature of function prototype is argument conversion.

Comments
  • Why do you want to discard the type from the return? does ChildClass not inherit ParentClass?
  • When I use it, I am actually casting it to ParentClass. I could make this a ParentClass* instead of void*, but that way I would have to type cast each entry into the array. I instead currently choose to cast it after I retrieve it from the array.
  • I miscommunicated through the question that I didn't want to use. I do want to use it. Modified the question accordingly.
  • In your first snippet you have declared fun4 twice, is that a typo?
  • Yup. Corrected.
  • Does this make the return type of the functions void?
  • @vc669 Yes, since you don't use it anyway. However, you can also use the lambdas to reconcile the return types, which since I guess ChildClass inherits from ParentClass is just []() -> ParentClasss * { return fun1(); }.
  • Did not realize that my usage(or lack thereof) would make a difference. I actually do intend to use it. I have updated the question accordingly and following your comment does the trick.
  • @Aconcagua yes, but consistency. One could avoid repetition by using a function that takes in all of the fun*'s at once and returns the array of wrapped functions as well.
  • @Aconcagua Almost: it gets compiled into a single jmp. Although the function's body will be inlined into the lambda if applicable.
  • Might be worth to mention that, as parameters are provided in header, if changing these, any translation units relying on need to be re-compiled to make these changes effective there as well...