C++11:我可以从多个 args 到 tuple,但是我可以从 tuple 到多个 args 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10766112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++11: I can go from multiple args to tuple, but can I go from tuple to multiple args?
提问by Thomas
Possible Duplicate:
How do I expand a tuple into variadic template function's arguments?
“unpacking” a tuple to call a matching function pointer
In C++11 templates, is there a way to use a tuple as the individual args of a (possibly template) function?
在 C++11 模板中,有没有办法使用元组作为(可能是模板)函数的单个参数?
Example:
Let's say I have this function:
示例:
假设我有这个功能:
void foo(int a, int b)
{
}
And I have the tuple auto bar = std::make_tuple(1, 2)
.
我有元组auto bar = std::make_tuple(1, 2)
。
Can I use that to call foo(1, 2)
in a templaty way?
我可以使用它以foo(1, 2)
模板方式调用吗?
I don't mean simply foo(std::get<0>(bar), std::get<1>(bar))
since I want to do this in a template that doesn't know the number of args.
我的意思不仅仅是foo(std::get<0>(bar), std::get<1>(bar))
因为我想在不知道参数数量的模板中执行此操作。
More complete example:
更完整的例子:
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
}
I should note that I'd prefer to not create one template that works for one arg, another that works for two, etc…
我应该注意,我不希望创建一个适用于一个参数的模板,另一个适用于两个参数,等等......
回答by Kerrek SB
Try something like this:
尝试这样的事情:
// 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));
}
Example:
例子:
#include <cstdio>
int main()
{
auto t = std::make_tuple("%d, %d, %d\n", 1,2,3);
call(std::printf, t);
}
With some extra magic and using std::result_of
, you can probably also make the entire thing return the correct return value.
通过一些额外的魔法和使用std::result_of
,您可能还可以使整个事物返回正确的返回值。
回答by Jonathan Wakely
Create an "index tuple" (a tuple of compile-time integers) then forward to another function that deduces the indices as a parameter pack and uses them in a pack expansion to call std::get
on the tuple:
创建一个“索引元组”(编译时整数元组),然后转发到另一个函数,该函数将索引推导出为参数包,并在包扩展中使用它们来调用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());
}
My implementation of index_tuple
is at https://gitlab.com/redistd/redistd/blob/master/include/redi/index_tuple.hbut it relies on template aliases so if your compiler doesn't support that you'd need to modify it to use C++03-style "template typedefs" and replace the last two lines of caller
with
我的实现index_tuple
是在https://gitlab.com/redistd/redistd/blob/master/include/redi/index_tuple.h但它依赖于模板别名所以如果你的编译器不支持你需要修改它用C ++ 03式“模板类型定义”并替换的最后两行caller
用
typedef typename redi::make_index_tuple<sizeof...(Args)>::type indices;
caller_impl(func, argtuple, indices());
A similar utility was standardised as std::index_sequence
in C++14 (see index_seq.hfor a standalone C++11 implementation).
std::index_sequence
在 C++14 中标准化了一个类似的实用程序(有关独立的 C++11 实现,请参阅index_seq.h)。