It's a little bit tricky trying to phrase this question.
So let's say I have a large number of functions that all have varying numbers of arguments - some have none, some have one, some have a few or many more. I receive the parameters for these functions in a vector. Normally, I can just call them like this:
#include <vector>
int my_functionA(std::string a) { /*...*/ return 1; }
int my_functionB(std::string a, std::string b) { /*...*/ return 2; }
void some_useful_function(std::vector<std::string> vec, int choice) {
if (choice == 1) {
// Error checking would happen here
int val = my_functionA(vec[0]);
// Do something with val
// ...
}
else if (choice == 2) {
// Error checking would happen here
int val = my_functionB(vec[0], vec[1]);
// Do something with val
// ...
}
}
Error checking would be making sure there are the correct number of arguments, etc. But this gets very tedious if I have a large number of functions, and the error checks and what I do with the return value are the same. I end up repeating the same ~15 lines of code 100 times, and if I ever decide I want to change or add something to that 15 line 'sequence', I'd have to redo it a hundred times.
It would make more sense if I could make a map from a choice to a data structure that has the function pointer and other information I'll need, and then the my_useful_function would be more like:
struct funcPointer {
funcPointer(void * f, int n) : fnc(f), numOfArgs(n) {};
void * fnc;
int numOfArgs;
};
std::map<int, funcPointer> = {
{1, funcPointer(my_functionA, 1)},
{2, funcPointer(my_functionB, 1)}};
void some_useful_function(std::vector<std::string> vec, int choice) {
if (map.count[choice] > 0) {
// Do stuff if map[choice].numOfArgs is insufficient
int val = map[choice].fnc(vectorSomehowConvertedToArguments);
// Do stuff with the return value
}
}
This answer with the 'index trick' got me really close, but since it requires a constant for the unpack_caller, I'm not sure how to mesh that into my map / data struct.
Aucun commentaire:
Enregistrer un commentaire