1

Suppose I have some functions which have the same parameters and datatype, and I want to push them into a std::vector and enumerate them. Is it possible to do this?

Pseudocode:

typedef int func(int, int);

int add(int a, int b)
{
    return a + b;
}

int minus(int a, int b)
{
    return a - b;
}

vector<func> operations = {add, minus};
for (auto operation : operations)
{
    // do something
}
  • 1
    Why not simply call the compiler? On a first view, the code should work... – Klaus Feb 24 '22 at 08:56
  • 4
    Function typedefs can be hard to read. I prefer `using func = int(*)(int, int)` but that's just style. I don't see any real problem either. – MSalters Feb 24 '22 at 09:00

1 Answers1

3

What you are missing in your code is a * in std::vector<func> because you want to store pointers to the function:

#include <vector>
#include <functional>
#include <iostream>
typedef int func(int, int);

int add(int a, int b)
{
    return a + b;
}

int minus(int a, int b)
{
    return a - b;
}

int main() {
    std::vector<func*> operations = {add, minus};
    for (auto operation : operations)
    {
    }
}

You could also use std::function for that purpose:

#include <vector>
#include <functional>

int add(int a, int b)
{
    return a + b;
}

int minus(int a, int b)
{
    return a - b;
}

int main() {
    std::vector<std::function<int(int,int)>> operations = {add, minus};
    for (auto operation : operations)
    {
        // do something
    }
}

Related question:

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • 1
    std::function has a lot overhead. In the given case it did not provide any additional functionality but wastes time and memory. – Klaus Feb 24 '22 at 09:01
  • 1
    [Linked question](https://stackoverflow.com/questions/3758121/how-can-i-store-function-pointer-in-vector) has an answer which shows how to do it without `std::function`. Best way depends on circumstances: whether or not you need `std::function`'s additional features (i.e. stored state). – anatolyg Feb 24 '22 at 09:04
  • @hyde Quite interesting ideas! I personally see no difference in robustness nor clarity by using a function pointer. If we instead of `typdef` use `using` it feels clear enough for me. And we can use lambdas already with function pointers, as long we have no need to store data there. Adding overhead for nothing is for my point of view not an option. And by simply changing a single line later to make capturing lambdas possible, is not a big deal. We see so many wasting code these days... starting with using std::string instead of const char* for simple text messages... only my two cents! – Klaus Feb 24 '22 at 09:29
  • @Klaus yes I agree that `std::function` can have a noticeable overhead and one has to think over which one to use. As you said the same is true with anything that adds certain features (like `std::string`, `std::unique_ptr`, ...). In most of the cases where I had the need to use function pointers the overhead of `std::function` over raw function pointers was negligible. But using raw pointers added complexity to the program logic because I normally only needed it when I also had the need to "pass" context with it. – t.niese Feb 24 '22 at 10:00