I am trying to loop through an array of functions stored in a vector, and i want to call each of them by the iterator pointer object, but something like this:
itr->funcs[i](5); // call the ith index function && pass int 5 as param
is not the solution i guess, what is the solution then ?
Below is my code, please check the last for loop in the code.
#include <iostream>
#include <string>
#include <vector>
// to be able to take other functions as arguments in a function
#include <functional>
using namespace std;
// receive other functions inside a function
// syntax: return_type function_name(std::function<return_type(parameter_lists)>func_name, parameter_lists)
double doMath(std::function<double(double)> someOtherFunction, double num){
return someOtherFunction(num);
}
double multBy2(double d){
// b'coz x is pointing to multBy2 the word 'someOtherFunction' in the
// above function behaves like an alias for this function 'multBy2'
return d * 2;
}
double multBy3(double d){
return d * 3;
}
int main (){
// dec && init
auto x = multBy2; // x pointing to multBy2 now
std::cout << "2 * 5.1 : " << x(5.1) << "\n";
std::cout << "multBy2 will be called: " << doMath(x, 6.1) << "\n";
std::cout << "multBy2 will be called, again: " << doMath(x, 6.1) << "\n";
// store different functions inside a vector
// you must use the same signature type functions
std::vector<function<double(double)>> funcs(2);
funcs[0] = multBy2; // multBy2 stored at the zeroth index
funcs[1] = multBy3; // multBy3 stored at the first index
// check
// funcs[0](10), pass value by index
std::cout << "2 * 10 = " << funcs[0](10) << "\n";
std::cout << "3 * 10 = " << funcs[1](10) << "\n";
// loop through them
for (auto itr = funcs.begin(); itr != funcs.end(); itr++){
// iterate through the functions
// itr->funcs[1](10); // I KNOW THIS IS WRONG, WHAT SHOULD I WRITE HERE?
}
return 0;
}
The variable itr
is an iterator, which is basically a pointer, i.e. they both point to to an object. In this case the iterator is pointing to a function. You can get to the function by dereferencing itr
(much like a pointer) with *itr
. Then you can use this object like it's a function (because it is one):
for (auto itr = funcs.begin(); itr != funcs.end(); ++itr)
(*itr)(10); // like calling func[i](10)
Since it's an iterator, you might also want to use the ->
operator, so that you can use the pointed at object directly. Unfortunately, if you tried to do what might seem like the obvious thing:
itr->(10); // error
the syntax of the language just doesn't allow it (parentheses can be tricky to figure out, even for a compiler). Fortunately, the language does have a way of allowing you to explicitly say what you mean, which is, "I just want to treat it like a function, so I can call it with ()
". There is a function called the call operator which is spelled operator()
that you can use. The syntax for that is:
for (auto itr = funcs.begin(); itr != funcs.end(); ++itr)
itr->operator()(10);
However, this syntax does seem to defeat the purpose of using the convenient ->
operator in the first place.
However, I recommend that you use a range-for loop here (it's usually the better choice if you can use it). The syntax is much clearer at expressing the intent of the code:
for (auto &func : funcs) // for every function in funcs
func(10); // use the function
Here's a working demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With