Bạn phải sử dụng ::std::tuple<Args...>
để lưu trữ. Nhưng sau đó câu hỏi là làm thế nào để giải nén nó khi bạn cần nó. Cho rằng bạn cần sử dụng một kỹ thuật gọi là 'chỉ số'.
Vì vậy, đây là một liên kết đến một nơi mà tôi đã thực hiện gần như những gì bạn đang muốn làm. Lớp có liên quan nhất ở đây là loại trung tâm là suspended_call
.
https://bitbucket.org/omnifarious/sparkles/src/tip/sparkles/deferred.hpp?at=default
Chỉ trong một chút, tôi sẽ trích xuất các bit phù hợp nhất và đặt chúng về mã của bạn.
This line:
auto saved_args = ::std::make_tuple(::std::move(args)...);
tiết kiệm các đối số vào một tuple. Tôi đã sử dụng ::std::move
ở đó và tôi nghĩ đó là điều phải làm. Nhưng có thể tôi sai và tôi nên sử dụng ::std::forward
. Tôi chưa bao giờ rõ ràng về sự khác biệt chính xác ngoài ý định báo hiệu.
Mã thực sự thực hiện cuộc gọi với các đối số đã lưu có thể được tìm thấy here. Bây giờ mã đó khá cụ thể cho chính xác những gì tôi đang làm. Bit thực hiện thủ thuật chỉ mục liên quan đến việc tạo một gói các số nguyên ánh xạ tới các chỉ mục để sử dụng làm đối số mẫu ::std::get<I>
. Một khi bạn có gói số nguyên này, bạn có thể sử dụng nó để mở rộng cuộc gọi đến ::std::get
để nhận tất cả các phần tử tuple dưới dạng đối số riêng lẻ.
tôi sẽ cố gắng đưa ra với mã nào đó theo một cách tương đối đơn giản:
#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));
}
Rất nhiều mã này được mượn từ this page on the indices trick.
Ngoài ra, đó là một mẫu mà bạn sẽ phải điều chỉnh một chút cho tình huống cụ thể của bạn. Về cơ bản, chỉ cần gọi call(nestFunc, saved_args)
ở đâu đó.
'std :: tuple '- cũng,' std :: bind' và 'std :: function' và tất cả những thứ thú vị đó. –
Xeo