С одной стороны, у меня есть список указателей на функции с различными сигнатурами, хранящимися на карте, которая сопоставляет каждую функцию с идентификатором функции. Указатели функций набираются в шаблонных классах, таких как:
typedef R (T::*SetPtr_t) (A)
typedef R (T::*SetPtr_t) (A, B)
typedef R (T::*SetPtr_t) (A, B, C)
и т.п.
С другой стороны, у меня есть другая карта, которая отображает один и тот же идентификатор функции в блок памяти, который сохраняет параметры функции.
Я ищу автоматизированный способ вызова функции через указатель функции с первой карты путем передачи аргументов, хранящихся в непрерывном блоке памяти со второй карты. Я ищу способ сделать это так, чтобы мне не пришлось вручную кодировать каждый случай, когда я извлекал аргументы и передавал их в функцию, так как есть сотни этих функций.
Что касается проблемы, которую мы пытаемся решить, мы в основном стараемся избегать ручного кодирования многих этих вызовов функций, и она хорошо работает для случая, когда у вас есть только функции, которые принимают один параметр, дизайн изначально для. Проблемы возникают, когда вы пытаетесь поддерживать переменное количество аргументов.
Единственное, что я нашел до сих пор, это сохранить параметры в стеке и вызвать функцию вручную, что-то вроде этого: C функция вызова вручную со стеком и регистром. Но это решение показалось слишком запутанным. Я надеялся на что-то большее С++ - по возможности.
Надеюсь, вопрос, по крайней мере, достаточно ясный.
Ну, поскольку Grady Player прокомментировал исходную запись, объекты функции и bind (либо boost::bind
/boost::function
либо std::bind
/std::function
из С++ 11), как правило, это путь, если вам необходимо сохранить вызовы функций (указатели функций или функторы) и их параметры.
Скорее всего, вы могли бы сохранить параметры на своей карте в качестве объектов привязки вместо этого и просто вызвать объект bind/function, который позаботился бы о вызове исходной функции с ее связанными аргументами.
С другой стороны, если вы предпочитаете или хотите сохранить текущую карту, вместо того, чтобы вручную записывать вызовы, вы можете использовать функцию вариационного шаблона (функцию С++ 11) для их создания, например:
template<typename R, typename...ParameterTypes typename... ArgumentTypes>
void execute( R (*func)(ParameterTypes...), ArgumentTypes... arguments )
{
func( static_cast<ParameterTypes...>( arguments... ) );
}
где static_cast
- это всего лишь пример конвертации или распаковки, который вам может понадобиться, чтобы "адаптировать" структуру arguments
которую вы держите на карте, к фактическим аргументам вызова.
Трудно дать какие-либо рекомендации без дополнительной информации о вашей конкретной ситуации, но я считаю, что привязка и/или вариационные tempaltes могут быть способом ее решения.