我想了解C++中的参数解包
I would like to understand parameter unpacking in C++
我试图使用可变参数模板编写我的第一个程序。专门打包延迟函数调用的参数。我最初调用函数指针的假设
如下所示不起作用:template<typename... params>
void TypeX<params...>::delayed_call()
{
auto xs = get_saved_args(); // returns tuple
(*func)(xs...);
}
环顾四周后,我找到了这个答案C++11:我可以从多个参数转到元组,但是我可以从元组到多个参数吗?
用户Kerrek SB的答案有效,并且看起来比其他替代方案更好。不幸的是,我只部分理解它。这是他的回答:
// 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));
}
我知道这是一个递归解决方案,一旦达到部分专用版本,它就会终止。不过,我无法理解流程,以及f(std::get<N>(std::forward<Tuple>(t))...);
究竟是如何变成一个未打包的电话的。理想情况下,我希望看到从用户可调用函数调用一直到流程的详细描述。
盯着这个看了一会儿后,我终于得出了一些合乎逻辑的东西。这是我目前对这个解包实现的理解。为了清楚起见,我在代码中添加了注释。
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,
// This is the tricky part: Initial N... is empty, so
// sizeof...(N) is going to be 0, which is fed to next
// call_impl. On subsequent invokation of "call" N will
// contain a single entry - '0'. All subsequent invokations
// will keep adding numbers to N until
// Total == 1 + sizeof...(N)
// evaluates to true. At that point template
// specialization below gets invoked and completes the
// recursive chain.
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)
{
// This is the last call in the recusrive chain, so int... N is
// actually a tuple of numbers (unless the function being invoked takes
// no arguments)
// Ellipsis(...) causes the line below to be expanded to however many
// numbers the int... N contains:
// f(std::get<0>(std::forward<Tuple>(t)),
// std::get<1>(std::forward<Tuple>(t)),
// std::get<2>(std::forward<Tuple>(t))
// ...
// );
f(std::get<N>(std::forward<Tuple>(t))...);
}
};
// user invokes this
template <typename F, typename Tuple>
void call(F f, Tuple && t)
{
// Strip all qualifiers from Tuple: constness, volatility, reference
// and return the typedef of underfyling Tuple type
typedef typename std::decay<Tuple>::type ttype;
// ttype should now be a plain tuple type, so tuple_size will return its
// size
// IMPORTANT: The int... N is not given below, which drives the recursive
// compilation
call_impl<F,
Tuple,
0 == std::tuple_size<ttype>::value, // for no argument functions this is
// always true, which doesn't trigger recursive call_impl, but
// immediately drops to partially specialized call_impl, which
// invokes the given function.
std::tuple_size<ttype>::value
/*int... N would go here, but nothing is supplied */
>::call(f, std::forward<Tuple>(t));
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 了解布尔运算符==(参数 1,参数 2)
- 了解'this'或其他参数是否为右值
- 了解sigwait()及其如何设置参数
- 了解 std::function 的晦涩模板参数
- 了解可变参数模板
- 了解错误 C2664:无法转换参数 1
- 了解 glm::ortho() 的参数如何影响投影后的顶点位置
- 了解 void f(const T¶m) 中的参数类型
- 了解随机数生成器调用中的C 参数
- 了解如何声明模板参数的默认值
- 递归函数是否可以在不将常量作为参数发送的情况下了解首次调用它的函数中的常量
- 将对象传递给参数时了解堆栈
- C++了解默认参数中的引用
- 需要了解参数何时在 c++ 中作为 (className&arg) 传递
- 我想了解C++中的参数解包
- 了解完美转发和可变参数模板的片段