目前我在尝试存储参数包时遇到问题,这是设计的示例代码:
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)...);
}
这是问题涉及的所有内容的示例,我需要在我的nest结构中存储以后调用的参数。此外,如果你有一个解决方案来存储它,但设置它与我的不同,也请让我知道这一点。感谢。
答案 0 :(得分:20)
从2018年编辑:在C ++ 17中,这个问题的答案是不同的。您仍然需要将参数存储在::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)...);
将参数保存到元组中。我在那里使用::std::move
,我认为这是正确的做法。但是我可能错了,我应该使用::std::forward
。除了发出信号意图之外,我从未明确确切的区别。
可以找到实际使用已保存参数进行调用的代码here。现在代码对我正在做的事情非常具体。实现索引技巧的位涉及创建一组整数,这些整数映射到索引以用作::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));
}
很多代码都来自this page on the indices trick。
此外,这是一个样本,你必须稍微适应你的具体情况。基本上,只需在某处调用call(nestFunc, saved_args)
。
答案 1 :(得分:7)
我知道它已经有一段时间了,但我有类似的需求,并提出了这个解决方案,希望它可以帮助某人:
#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...);
}