0

I have a vector of function pointers (void (*)()) representing a list of actions you have already taken. How could I pop out the last two and make it into one function pointer and put it back in the list?

Example:

void link_last_two(std::vector<void (*)()> actions) {
    if(actions.size() <= 1) return;
    void (*first)() = actions.back();
    actions.pop_back();
    void (*second)() = actions.back();
    actions.push_back([](){first(); second();});
}
Czipperz
  • 3,268
  • 2
  • 18
  • 25
  • 7
    Use `std::function` instead of raw function pointers. – Basile Starynkevitch Aug 28 '15 at 05:36
  • You can do it using a hackish solution. If you have control over the code, use `std::function` instead, as suggested also by @BasileStarynkevitch. – R Sahu Aug 28 '15 at 05:39
  • 2
    A function pointer is just a pointer - an address in memory where the machine code of a function is located. "first" points to some address, "second" points to some address; which address do you want the new function to point? There's no existing function to point to, and you probably are not asking about generating machine code for a fresh new function and pointing to that. That's why you should use something else for describing functions rather than pointers. std::function is a great choice. – jkff Aug 28 '15 at 05:41
  • @BasileStarynkevitch Isn't that INCREDIBLY SLOW? I can change the source (I haven't coded it yet) – Czipperz Aug 28 '15 at 05:42
  • I doubt there is any way to accomplish what you want. You cannot dynamically synthesize a static function, and get a pointer to it. – Lingxi Aug 28 '15 at 05:50
  • If you want to be able to combine two actions into one, then you should not have a vector of fctn ptrs, but a `vector`. Shouldn't be hard to implement such a class, and could be fun. – Paolo M Aug 28 '15 at 06:36
  • 1
    @Czipperz, http://stackoverflow.com/questions/14306497/performance-of-stdfunction-compared-to-raw-function-pointer-and-void-this – SingerOfTheFall Aug 28 '15 at 06:40

1 Answers1

0

With void(*)(), you can't. This is simply a consequence of the fact that there is no context whatsoever. You can create a function void helper() and store a pointer to that, but how would helper know which two functions to call?

As noted, std::function<void(void)> does have the required context. Alternatively, store a list of

std::pair<void*, union {
   void(*)(void) no_context;
   void(*)(void*) context;
  }>

If the first void* is nullptr, call the no_context function, else call the context function passing the non-null void* pointer.

MSalters
  • 173,980
  • 10
  • 155
  • 350