Предположим, что у меня есть некоторые отражения метаданных, который имеет следующую информацию:Вызывающие ++ (участник) функции C динамически
enum class type { t_int, t_double, t_str /* etc... */ };
struct meta_data
{
void* function;
void* instance;
std::vector<type> param_types;
};
std::map<std::string, meta_data> ftable;
Я хотел бы вызывать функции в этой карте, учитывая имена функций и параметров как в строки. Моя проблема заключается не в преобразовании параметров (например, с помощью boost::lexical_cast
), а в том, что вы выбрали нужный тип указателя функции и вызвали функцию. Если я разрешу 8 типов и максимум 8 параметров, в моем коде уже много ветвей. То, что я хочу, чтобы избежать (псевдокод):
switch (md.param_types.size()) { case 0: cast function pointer, call it break; case 1: switch (md.param_types[0]) { case t_int: int param = boost::lexical_cast(param_strings[0]); cast function pointer, call with param case ... } break; case 2: switch (md.param_types[0]) { case t_int: int param = boost::lexical_cast(param_strings[0]); switch (md.param_types[1]) {...} // second param type.. } break; case n... }
Это взрывает очень быстро с числом параметров и возможных типов. Я смотрю какое-то решение по линиям (псевдо-код):
for (auto& p : paramter_strings)
{
convert p to a variable of matching type (type id comes from meta_data).
store value
}
call function with stored values
т.е. нет ветвления для вызова функции. Как я могу сделать это с наименьшим количеством кода шаблона (возможно, с поддержкой произвольного количества параметров)? Вы можете думать об этом как о создании привязок к пользовательскому языку сценария.
к сведению, что в большинстве реализаций есть определенные типы указателей функций, которые больше, чем пустота *. Также обратите внимание, что идея вашего стека не будет работать вообще, поскольку соглашения о вызовах широко варьируются, а также часто зависят от типа переданного параметра. Единственное, что приходит мне на ум, которое могло бы помочь вам, - это рекурсивные вызовы шаблонов, добавляющие один за другим параметр, а затем, наконец, вызов «реальной вещи». Но вся идея настолько безумна ... – PlasmaHH
Вы отметили этот вопрос как 'lua'. Это стек Lua или стек архитектуры? Кроме того, если вы вызываете функции-члены, то функция 'function' должна иметь тип' void (dummy :: * function)() 'по крайней мере, а затем вы можете' reinterpret_cast' ввести правильный тип функции. – Simple
@ Простой, никакой тег lua не был ошибкой, у меня был черновик вопроса на этом ПК, который я удалил, но забыл повторно пометить. исправлено. –