Ответ 1
Вы должны использовать ::std::tuple<Args...>
для его сохранения. Но тогда возникает вопрос, как распаковать его, когда вам это нужно. Для этого вам нужно использовать технику под названием "индексы".
Итак, вот ссылка на место, где я сделал примерно то, что вы хотите сделать. Самым значимым классом здесь является то, что центральная часть suspended_call
.
https://bitbucket.org/omnifarious/sparkles/src/tip/sparkles/deferred.hpp?at=default
Немного, я извлечу наиболее релевантные биты и поставлю их с точки зрения вашего кода.
auto saved_args = ::std::make_tuple(::std::move(args)...);
сохраняет аргументы в кортеж. Я использовал ::std::move
там, и я думаю, что это правильно. Но возможно, я ошибаюсь, и я должен использовать ::std::forward
. Я никогда не видел четкой разницы, кроме намерения сигнализации.
Код, который фактически выполняет вызов с сохраненными аргументами, можно найти здесь. Теперь этот код достаточно специфичен для того, что я делаю. Бит, который реализует трюк индексов, включает создание пакета целых чисел, который сопоставляет индексы для использования в качестве аргументов шаблона ::std::get<I>
. После того, как у вас есть этот набор целых чисел, вы можете использовать его, чтобы развернуть вызов до ::std::get
, чтобы получить все элементы кортежа как отдельные аргументы.
Я попытаюсь придумать код, который делает это относительно простым способом:
#include <tuple>
#include <cstddef>
#include <string>
#include <utility>
template < ::std::size_t... Indices>
struct indices {};
template < ::std::size_t N, ::std::size_t... Is>
struct build_indices : build_indices<N-1, N-1, Is...>
{};
template < ::std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...>
{};
template <typename FuncT, typename ArgTuple, ::std::size_t... Indices>
auto call(const FuncT &f, ArgTuple &&args, const indices<Indices...> &)
-> decltype(f(::std::get<Indices>(::std::forward<ArgTuple>(args))...))
{
return ::std::move(f(::std::get<Indices>(::std::forward<ArgTuple>(args))...));
}
template <typename FuncT, typename ArgTuple>
auto call(const FuncT &f, ArgTuple &&args)
-> decltype(call(f, args,
build_indices< ::std::tuple_size<ArgTuple>::value>{}))
{
const build_indices< ::std::tuple_size<ArgTuple>::value> indices;
return ::std::move(call(f, ::std::move(args), indices));
}
int myfunc(::std::string name, const unsigned int foo)
{
return 0;
}
int foo(::std::tuple< ::std::string, const unsigned int> saved_args)
{
return call(myfunc, ::std::move(saved_args));
}
Многое из этого кода было заимствовано из этой страницы по трюку индексов.
Кроме того, этот тип образца, который вам придется немного адаптировать к конкретной ситуации. В принципе, просто позвоните call(nestFunc, saved_args)
где-нибудь.