Немного сложно сформулировать этот вопрос.
Итак, скажем, у меня есть большое количество функций, у всех из которых есть различное количество аргументов - у некоторых их нет, у некоторых есть, у некоторых есть несколько или много других. Я получаю параметры для этих функций в векторе. Обычно я могу назвать их так:
#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
// ...
}
}
При проверке ошибок проверяется правильное количество аргументов и т. Д. Но это становится очень утомительным, если у меня большое количество функций, а проверки ошибок и то, что я делаю с возвращаемым значением, в основном совпадают ( т.е. проверяя, что размер вектора соответствует числу аргументов). В итоге я повторяю очень похожие ~ 15 строк кода 100 раз, и если я когда-нибудь решу, что хочу изменить или добавить что-то к этой 15-строчной «последовательности», мне придется повторить это сто раз.
Было бы более разумно, если бы я мог сделать карту из выбора в структуру данных, которая имеет указатель функции и другую информацию, которая мне понадобится, и тогда my_useful_function будет больше похожа на:
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, 2)}};
void some_useful_function(std::vector<std::string> vec, int choice) {
if (map.count(choice) > 0) {
// Do stuff if map[choice].numOfArgs doesn't match vec size
int val = map[choice].fnc(vectorSomehowConvertedToArguments);
// Do stuff with the return value
}
}
Этот ответ с помощью «трюка с индексом» очень близко подошел ко мне, но, поскольку для unpack_caller требуется константа, я не уверен, как связать это с моей структурой карты / данных.