C ++ 11:我可以从多个参数到元组,但我可以从元组去多个参数?

可能重复:
如何将元组展开成可变参数模板函数的参数?
“解包”一个元组来调用一个匹配的函数指针

在C ++ 11模板中,有没有一种方法可以将元组用作(可能是模板)函数的单独参数?

例:
比方说我有这个function:

void foo(int a, int b) { } 

我有tuple auto bar = std::make_tuple(1, 2)

我可以用它来模仿foo(1, 2)吗?

我不是简单的foo(std::get<0>(bar), std::get<1>(bar))因为我想在一个不知道参数个数的模板中做这个。

更完整的例子:

 template<typename Func, typename... Args> void caller(Func func, Args... args) { auto argtuple = std::make_tuple(args...); do_stuff_with_tuple(argtuple); func(insert_magic_here(argtuple)); // <-- this is the hard part } 

我应该注意到,我宁愿不创build一个模板,适用于一个参数,另一个适用于两个,等等…

尝试这样的事情:

 // implementation details, users never invoke these directly namespace detail { template <typename F, typename Tuple, bool Done, int Total, int... N> struct call_impl { static void call(F f, Tuple && t) { call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t)); } }; template <typename F, typename Tuple, int Total, int... N> struct call_impl<F, Tuple, true, Total, N...> { static void call(F f, Tuple && t) { f(std::get<N>(std::forward<Tuple>(t))...); } }; } // user invokes this template <typename F, typename Tuple> void call(F f, Tuple && t) { typedef typename std::decay<Tuple>::type ttype; detail::call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t)); } 

例:

 #include <cstdio> int main() { auto t = std::make_tuple("%d, %d, %d\n", 1,2,3); call(std::printf, t); } 

用一些额外的魔法和使用std::result_of ,你也可以使整个事情返回正确的返回值。

创build一个“索引元组”(一个编译时间整数的元组),然后转发到另一个函数,该函数将索引推导为参数包,并在包扩展中使用它们来调用元组的std::get

 #include <redi/index_tuple.h> template<typename Func, typename Tuple, unsigned... I> void caller_impl(Func func, Tuple&& t, redi::index_tuple<I...>) { func(std::get<I>(t)...); } template<typename Func, typename... Args> void caller(Func func, Args... args) { auto argtuple = std::make_tuple(args...); do_stuff_with_tuple(argtuple); typedef redi::to_index_tuple<Args...> indices; caller_impl(func, argtuple, indices()); } 

我的index_tuple实现是在https://gitlab.com/redistd/redistd/blob/master/include/redi/index_tuple.h,但它依赖于模板别名,所以如果你的编译器不支持,你需要修改它使用C ++ 03风格的“模板types定义”,并用最后两行的caller代替

  typedef typename redi::make_index_tuple<sizeof...(Args)>::type indices; caller_impl(func, argtuple, indices()); 

一个类似的工具在C ++ 14中被标准化为std::index_sequence (参见独立C ++ 11实现的index_seq.h )。