2

Is it possible to create a vector that has functions pushed back?
I've tried doing something with pointers, but it only works with functions without parameters.

For example,

#include <iostream>
#include <vector>

using namespace std;

void printInt();

int main()
{
    vector<void (*)()> functionStack;

    functionStack.push_back(printInt);

    (*functionStack[0])();
}

void printInt()
{
    cout << "function works!" << 123 << endl;
}

That works, but not what I need.
The correct version of that would be a function that has parameters: void printInt(int a) and you could call it with different values like 4 or -1 but from the vector functionStack.

It's probably more complex if the functions in the vector are with different parameters, so let's assume that every function has the same type and amount of parameters.

3
  • 1
    What have you tried w.r.t. functions w/ arguments? It looks like you're basically there.
    – AndyG
    Commented Oct 8, 2019 at 14:34
  • 1
    Have you tried vector<void (*)(int)> functionStack; and, correspondingly, elsewhere, void printInt(int a);? Commented Oct 8, 2019 at 14:37
  • 2
    printStr in the question is just a typo I assume?
    – Ted Lyngmo
    Commented Oct 8, 2019 at 14:39

2 Answers 2

5

This:

void (*)()

is a function pointer taking no arguments. So change it to take the desired argument.

void (*)(int)

Like so:

void printInt(int x)
{
    cout << "function works!" << x << endl;
}

int main()
{
    vector<void (*)(int)> functionStack;

    functionStack.push_back(printInt);

    (*functionStack[0])(123);
}

You are correct in saying the functions must have the same type and number of parameters for this to be valid.

2
  • 2
    usually I am the one complaining about std::function when there is no need to... +1 Commented Oct 8, 2019 at 14:45
  • @acraig5075 Thanks! I'd be pretty interested to see how this is performed with different type and number of parameters, but as there's no immediate need I'll leave it for another day.
    – MrWhiteee
    Commented Oct 8, 2019 at 15:07
2

You basically had it already.

#include <iostream>
#include <vector>

using namespace std;

void printInt(int a);

int main()
{
    // Just needed the parameter type
    vector<void (*)(int)> functionStack;

    // Note that I removed the () from after the function
    // This is how we get the function pointer; the () attempts to
    // invoke the function
    functionStack.push_back(printInt);

    (*functionStack[0])(42);
}

void printInt(int a)
{
    cout << "function works! " << a << endl;
}

This is also a situation where std::function might be beneficial as well.

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

using namespace std;

void printInt(int a);

int main()
{
    // Similar syntax, std::function allows more flexibility at a 
    // lines of assembly generated cost. But it's an up-front cost
    vector<std::function<void(int)>> functionStack;

    functionStack.push_back(printInt);

    // I don't have to de-reference a pointer anymore
    functionStack[0](42);
}

void printInt(int a)
{
    cout << "function works! " << a << endl;
}
3
  • 1
    For what it's worth it's not necessary to dereference the function pointer either.
    – Quentin
    Commented Oct 8, 2019 at 14:51
  • Good to know. I don't mess with raw function pointers a lot. Just messy to me given that lambdas exist.
    – sweenish
    Commented Oct 8, 2019 at 14:53
  • @sweenish Thanks, I will take a look at std::function.
    – MrWhiteee
    Commented Oct 8, 2019 at 15:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.