Перенаправить скопированный std :: tuple - PullRequest
0 голосов
/ 25 сентября 2018

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

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, мне нужно "callable", чтобы его параметры были расширены из кортежа и переадресованы точно так, как они были переданы.в функции 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 Ответ

0 голосов
/ 25 сентября 2018

Если вы пытаетесь сделать однократный вызов, который передает свои аргументы, лучшее, что вы можете сделать с 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)...);
    };
}
...