c – 如何提取一组可选参数的参数,并使用它们来调用另一个函数

前端之家收集整理的这篇文章主要介绍了c – 如何提取一组可选参数的参数,并使用它们来调用另一个函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个可变函数动物园,它接受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.

猜你在找的C&C++相关文章