Перенаправить скопированный std::tuple

Мне нужна помощь. Мне нужно совершенным образом переслать кортеж определенным образом. Представь себе это

template <typename F, typename... Args>
auto package_task(F&& func, Args&&... args) -> std::function<void()>
{
    //for the purposes of this example imagine capture to be std::move and
    //to be inplace in the lambdas' capture.
    auto callable = capture(std::forward<F>(func));
    auto params = capture(std::make_tuple(std::forward<Args>(args)...));

    return [callable , params]() mutable { std::apply(callable, params); };
}

задача, которая упакована, будет выполнена позже в другом потоке, но когда я вызываю apply, мне нужно "вызываемое", чтобы его параметры были расширены из кортежа и переданы точно так, как они были переданы в package_task функция. Я не могу использовать forward_as_tuple так как я копирую / перемещаю аргументы и вызываемый файл, который будет выполнен позже. Мне нужно что-то вроде

template <typename F, typename... Args>
auto package_task(F&& func, Args&&... args) -> std::function<void()>
{
    //for the purposes of this example image capture to be std::move and
    //to be inplace in the lambdas' capture.
    auto callable = capture(std::forward<F>(func));
    auto params = capture(std::make_tuple(std::forward<Args>(args)...));

    return [callable , params]() mutable { std::apply_but_expand_as<Args&&…>(callable, params); };
}

Любые идеи были бы хорошы.

1 ответ

Решение

Если вы пытаетесь сделать однократный вызов, который передает свои аргументы, лучшее, что вы можете сделать с C++17 или более ранней версией:

template <typename F, typename... Args>
auto package_task(F&& func, Args&&... args) -> std::function<void()>
{
    return [func = std::forward<F>(func),
            args_tuple = std::make_tuple(std::forward<Args>(args)...)]
           () mutable
    {
        return std::apply([](auto&&... args){
            return std::invoke(
                std::forward<F>(func),
                std::forward<Args>(args)...
                );
        }, args_tuple);
    };
}

Это ты forward Args в кортеж, apply кортеж, а затем forward они отступают.


В C++20, благодаря P0780, это можно упростить до:

template <typename F, typename... Args>
auto package_task(F&& func, Args&&... args) -> std::function<void()>
{
    return [func = std::forward<F>(func),
            ...args = std::forward<Args>(args)] () mutable
    {
        return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
    };
}
Другие вопросы по тегам