Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put functions into vector and execute

Tags:

c++

c++11

vector

I want to make a vector/deque as function container.

This containter must take diffrent functions with diffrent arguments.

Example functions:

program_data::getInstance().function(int,std::string);
program_data::getInstance().foo(int);
program_data::getInstance().exam(int,std::string,double);

And could you show example code how to put these functions with arguments to std::vector / std::deque and execute?

I think that i should use std::function and std::bind but i dont know how to support diffrent functions with diffrent args size.

With arguments -> my functions (called function foo exam from program_data) do some actions using arguments.

For example: normally i execute this function:

program_data::getInstance().function(10,"halo");

And now i want to put these functions to std::vector // deque and execute with arguments which i put with function. i.e (if i put function above to vector and use (pseudocode) vector[0].run(); then my program run function program_data::getInstance().function(int,std::string);)

like image 885
Thomas Andrees Avatar asked Sep 02 '14 16:09

Thomas Andrees


2 Answers

Absolutely, use std::vector<std::function<void()>> - that is, a vector of type-erased function containers that can hold any object that is callable without arguments:

std::vector<std::function<void()>> vector;

// populate the vector
vector.push_back([]{ program_data::getInstance().function(10,"halo"); });

// execute items in the vector
vector[0]();

Here I'm populating the vector with a captureless lambda; you can also use lambdas with captures, bind-expressions (std::bind), and other callable objects.

If you use a lambda with a capture, you need to ensure that captured variables are either captured by value or have a lifetime that contains that of the collection of callables:

std::string tmp;
vector.push_back([&tmp]{ program_data::getInstance().something(tmp); });
like image 118
ecatmur Avatar answered Oct 25 '22 04:10

ecatmur


I would suggest using std::function and lambda expressions:

std::vector<std::function<void()>> functions;
functions.push_back([](){ program_data::getInstance().function(123, 456, "str"); });

This adds one function in your vector 'functions'. By calling functions[0](), this will call the lambda expression which then calls your function with 123, 456 and "str" as arguments.

like image 27
Fabien Avatar answered Oct 25 '22 05:10

Fabien