首页 > 解决方案 > 在 C++ 中的数据成员中存储带有变量参数的函数引用

问题描述

我想在类数据成员中存储具有可变数量参数的函数引用,然后按如下方式调用它:

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> && ...));

    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 &&, Arguments> && ...)>>
    explicit ExecuteAction(std::string &option_name,
                           ForwardFunction &&function,
                           ForwardArguments &&... 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 &&function, Arguments &&... 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();

然而,该解决方案存在以下问题:

C是否有C++20满足我要求的实现?

标签: c++classtemplatesvariadic-templatesc++20

解决方案


推荐阅读