C++ 在可变模板中传递参数组

C++ 在可变模板中传递参数组,c++,templates,variadic-templates,C++,Templates,Variadic Templates,可变模板对于执行递归操作非常有用。在这种情况下,我希望每个递归调用对两个参数进行操作,这样就不必重复调用同一个函数。为了实现这一点,我可以写: f() {} template<typename M, typename N, typename... Rest> f(M arg1, N arg2, Rest... rest) { doStuff(arg1, arg2); f(rest); } 但是,如果调用的格式不是很好,并且所有参

可变模板对于执行递归操作非常有用。在这种情况下,我希望每个递归调用对两个参数进行操作,这样就不必重复调用同一个函数。为了实现这一点,我可以写:

f() {}

template<typename M,
         typename N,
         typename... Rest>
f(M arg1, N arg2, Rest... rest)
{
    doStuff(arg1, arg2);
    f(rest);
}
但是,如果调用的格式不是很好,并且所有参数都在一行上,或者列在错误的位置被拆分,那么它将变得非常不可读。尤其是当通话可能包含十几对左右时。我试图通过要求传入成对的参数包来解决这个问题。我希望函数的调用方式如下:

f({arg1a, arg1b},
  {arg2a, arg2b},
  {arg3a, arg3b});

这似乎主要是失败的,因为初始值设定项列表没有推导成一对。我可以对每一组参数调用make_pair,但这只解决了一个可读性问题和另一个可读性问题。有没有办法让这种调用语法起作用?参数在对之间或对内不相同。

抱歉,这是不可能的:从大括号列表到用户定义类型的隐式类型转换。唯一可能的转换是针对
std::initializer\u list
,但只能针对相同类型或可转换类型进行转换

既然如此,我会提供这个,作为一种可能性

template <typename M, typename N>
void doStuff(M&&, N&&) {}

template <typename M, typename N>
struct MyRepeater;

template <typename M, typename N>
MyRepeater<M, N> f(M&& one, N&& two);

template <typename M, typename N>
struct MyRepeater {
  template <typename I, typename J>
  MyRepeater<I, J> operator()(I&& one, J&& two) const {
    return f(std::forward<I>(one), std::forward<J>(two));
  }
};

template <typename M, typename N>
MyRepeater<M, N> f(M&& one, N&& two) {
  doStuff(one, two);
  return MyRepeater<M, N>();
}

int main() {
  f(Foo1(), Foo2())(Bar1(), Bar2())(Bar2(), Foo1());
}
模板
void doStuff(M&&,N&&{}
模板
struct-MyRepeater;
模板
我的中继器f(M&&1,N&&2);
模板
结构MyRepeater{
模板
MyRepeater运算符()(I&&one,J&&two)常量{
返回f(std::forward(一),std::forward(二));
}
};
模板
我的中继器f(M&&1,N&&2){
多斯塔夫(一、二);
返回MyRepeater();
}
int main(){
f(Foo1(),Foo2())(Bar1(),Bar2())(Bar2(),Foo1());
}

当然,缺点是,只有为了可读性,你才需要两个人编写一些额外的代码(在我看来,这是一个不错的动机)。

这似乎令人惊讶,但我发现最好的解决方案实际上是“过去的爆炸”,根本不使用变量

struct F {
    template <class M, class N>
    F& operator()(M arg1, N arg2) { 
        doStuff(arg1, arg2);
        return *this;
    }
};

F{} (arg1a, arg1b)
    (arg2a, arg2b);
struct F{
模板
F&运算符()(M arg1,N arg2){
doStuff(arg1、arg2);
归还*这个;
}
};
F{}(arg1a,arg1b)
(arg2a,arg2b);

等等。尽管如此,我还将注意到,clang格式并不能很好地格式化它。因此,我又做了一些稍微不同的事情。

可以
arg1a
arg1b
arg2a
arg2b
。。。都是不同类型的?是的。在我的例子中,它们都是Qt连接的成员函数指针,但每个函数都可以接受不同的参数。恐怕语言没有办法做到这一点<代码>{arg1a,arg1b}没有类型,因此无法推断类型。使用定界标记是否可以接受
f(arg1a,arg1b,delimiter,arg2a,arg2b,delimiter,arg3a,arg3b)
如果每个组不正好是两个元素,则至少会导致编译时错误。
struct F {
    template <class M, class N>
    F& operator()(M arg1, N arg2) { 
        doStuff(arg1, arg2);
        return *this;
    }
};

F{} (arg1a, arg1b)
    (arg2a, arg2b);