目前我在尝试存储参数包时遇到问题,这是设计的示例代码:
template<typename Func, typename... Args>
void handleFunc(Func func, Args&&... args) {
struct nest {
Func nestFunc;
Args... nestArgs; // I DONT KNOW WHAT TO DO HERE
void setup(Func func, Args... args) {
nestFunc = func;
nestArgs = (args)...; // SO I CAN SET IT HERE
}
// Later I will forward this and run the function with its arguments
unsigned process() {
nestFunc(std::forward<Args>(nestArgs)...); // USE IT HERE
return 0;
}
};
nest* myNest;
myNest->setup(func, (args)...);
}
Run Code Online (Sandbox Code Playgroud)
这是问题所涉及的所有内容的示例,我需要存储参数以便稍后在我的nest结构中调用.此外,如果你有一个解决方案来存储它,但设置它与我的不同,也请让我知道这一点.谢谢.
Omn*_*ous 22
编辑自2018年:在C++ 17中,这个问题的答案是不同的.你仍然需要将你的参数存储在a中::std::tuple,但是当调用时,函数会处::std::apply理解压缩这个元组并为你调用函数.如果你需要使用索引技巧::std::apply来做除了什么之外的东西,还有你应该调查::std::integer_sequence的关联辅助函数::std::make_index_sequence.
现在回到2013年的C++ 11/14答案.
你必须用来::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)...);
Run Code Online (Sandbox Code Playgroud)
将参数保存到元组中.我在::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));
}
Run Code Online (Sandbox Code Playgroud)
很多这段代码都是从index这个页面借来的.
此外,这是一个样本,你必须稍微适应你的具体情况.基本上,只是打电话给call(nestFunc, saved_args)某个地方.
小智 11
我知道已经有一段时间但我有类似的需求并提出了这个解决方案,希望它可以帮助某人:
#include <functional>
template<typename Func, typename... Args>
struct nest {
std::function<void()> callBack;
void setup(Func func1, Args... args) {
callBack = [func1, args...]()
{
(func1)(args...);
};
}
unsigned process() {
callBack();
return 0;
}
};
template<typename Func, typename... Args>
void handleFunc(Func func, Args&&... args) {
nest<Func, Args...> myNest;
myNest.setup(func, args...);
}
Run Code Online (Sandbox Code Playgroud)