我有一个可变函数动物园,它接受N个参数,其中N在编译时已知(它是包含该函数的类的模板参数).
template <int N> struct B { template <typename... Args> static void zoo(Args... args) { static_assert(size of...(args) == N,""); // do something } };
我有另一个可变函数foo,它接受M个参数,其中M> N并且在编译时已知(它是包含该函数的类的模板参数).我有一个静态的index_array,其中包含要传递给动物园的foo参数的索引.
从foo的身体,我想称之为动物园通过foo参数的选定子集.
这样做最好的方法是什么?理想地实现完美的内联,即所有东西都编译成一个没有函数指针的指令的指令?
template<int...I> struct indices { static constexpr int N = sizeof...(I); }; template <int M,typename...X> struct A { // here I am simplifying,in reality IS will be built at compile time based on X typedef indices<0,2,3> IS; template <typename... Args> static void foo(Args... args) { static_assert(size of...(args) == M,""); // do some magic to achieve the function call described in pseudo-code // B<IS::N>::zoo(args(IS(0),IS(1),IS(2))) // ideally this should be perfectly inlined to just have the call above } };
请注意,上述代码是简化我的问题,旨在说明问题.
编辑:
如下所述,我描述了用例:
我正在玩一个基于模板的库驱动微控制器引脚.微控制器具有多个端口(以存储器中的字节可访问),并且每个端口具有多达8个引脚(位). A类是通过模板参数X的一组引脚,其中每个引脚定义为引脚. B类操纵同一端口上的所有引脚. A :: foo是修改某些引脚的函数,其参数与X模板参数包中指定引脚的顺序相同. foo需要通过端口将参数分组并分派到表示各个端口的B类,其中所有参数在单个指令中被融合并写入控制器.
解决方法
您可以创建一个帮助器来提取nth_arg,如下所示:
template <int I> struct ignore { template <typename T> ignore(T&&) // This constructor accepts anything { } }; template <typename T> struct nth_arg; template <size_t... DropIndexes> struct nth_arg<std::integer_sequence<size_t,DropIndexes...>> { template <typename Arg,typename... Rest> static decltype(auto) get(ignore<DropIndexes>...,// ignore args 0...n-1 Arg&& arg,Rest&&...) // also ignore the rest { return std::forward<Arg>(arg); // return nth arg } };
然后打电话
template <int... Is,typename... Args> static void call_zoo(indices<Is...>,Args&&... args) { B<sizeof...(Is)>::zoo(nth_arg<std::make_index_sequence<Is>>::get( std::forward<Args>(args)...)...); } template <int M> struct A { typedef indices<0,3> IS; template <typename... Args> static void foo(Args... args) { static_assert(sizeof...(args) == M,""); call_zoo(IS{},std::forward<Args>(args)...); } };
如果您使用C 11,您可以轻松滚动自己的integer_sequence.