#c #class #templates #variadic-templates #c 20
#c #класс #шаблоны #переменные-шаблоны #c 20
Вопрос:
Я хочу сохранить ссылку на функцию с переменным числом аргументов в элементе данных класса и вызвать ее позже следующим образом:
auto my_action = new ExecuteAction("Add", add, 1, 2);
std::vector<ExecuteAction *> execute_actions;
execute_actions.push_back(my_action);
// ...
auto my_action_retrieved = execute_actions.at(0);
my_action_retrieved->execute();
Обратите внимание, что add()
, например, определяется следующим образом:
void add(int a, int b) {
std::cout << a b << std::endl;
}
Самое близкое решение, которое я мог получить до сих пор, заключается в следующем:
template<typename Function, typename... Arguments>
class ExecuteAction {
static_assert(!(std::is_rvalue_reference_v<Arguments> amp;amp; ...));
std::string option_name;
Function function;
std::tuple<Arguments...> arguments;
public:
template<typename ForwardFunction, typename... ForwardArguments,
typename = std::enable_if_t<(std::is_convertible_v<ForwardArguments amp;amp;, Arguments> amp;amp; ...)>>
explicit ExecuteAction(std::string amp;option_name,
ForwardFunction amp;amp;function,
ForwardArguments amp;amp;... arguments)
: function(std::forward<ForwardFunction>(function)),
arguments{std::forward<ForwardArguments>(arguments)...} {
this->option_name = option_name;
}
void execute() {
std::apply(function, arguments);
}
};
template<typename Function, typename... Arguments>
auto make_execute_action(std::string option_name, Function amp;amp;function, Arguments amp;amp;... arguments) {
return new ExecuteAction<std::decay_t<Function>, std::remove_cv_t<std::remove_reference_t<Arguments>>...>
(option_name, std::forward<Function>(function), std::forward<Arguments>(arguments)...);
}
Этот код может быть успешно вызван следующим образом:
auto add_action = make_execute_action("Add", [](int a, int b) {
std::cout << a b << std::endl;
}, 1, 2);
add_action->execute();
Однако это решение имеет следующие проблемы:
- Функции должны передаваться с помощью лямбда-выражения, но я хочу передавать ссылки на функции (как в примере выше)
- Использование универсального
std::vector
не представляется возможным, поскольку параметры шаблона должны быть определены конкретно
Существует ли реализация в C
или до C 20
, которая удовлетворяет моим требованиям?
Комментарии:
1. «Есть ли реализация на C» ? C? это опечатка?
2. @idclev463035818: Нет, я думал о
varags
том, что теоретически можно было бы использовать3. В C
var_args
тоже есть4.
std::function
иstd::bind
? Конечно, это требует, чтобы все функции имели одинаковую подпись.5. @Someprogrammerdude: но я хочу, чтобы аргументы были полностью произвольными по типу и количеству для передачи в ссылку на функцию при выполнении вызова