相应地解耦可变参数函数中结构的成员变量

decouple member variables of a struct in variadic function accordingly

我之前发过一个问题,。但是,它并没有完全解决我的问题,因为我没有准确地询问它。因此,我想重新措辞并详细解释我的问题。提前致谢!

假设我有一个结构 Outcome,它采用两个参数函数 Outcome cal_out(int, int) 来构造,并且可以通过 Outcome cal_out(Outcome, int, int) 和两个附加参数递归计算,即 xy.

struct Outcome {
  int valueX;
};

Outcome cal_out(int x,int y) {
 int z = some_algo(x, y);
 return Outcome{z};
}

Outcome cal_out(Outcome rhs, int x, int y){
  int z = some_algo(rhs, x, y);
  return Outcome {z};
}

template<class... Ts>
Outcome cal_out(Outcome rhs, int x, int y, Ts... ts){
  return cal_out(cal_out(rhs, x, y), ts...);
}

现在我的问题是,我有一个这样的结构 Coord

template<int X, int Y>
struct Coord {
 static const int valueX = X;
 static const int valueY = Y;
};

我想问一下如何调用 get_out_from_coords() 来得到结果,即

Outcome out = get_out_from_coords<Coord<1,2>, Coord<3,4>, Coord<5,6> >();

我的伪实现不起作用

template<class COORD>
Outcome get_out_from_coords() {
  return cal_out(COORD::valueX, COORD::valueY);
}

template<class COORD1, class COORD2>
Outcome get_out_from_coords() {
  return cal_out(get_out_from_coords<COORD1>(), COORD2::valueX, COORD2::valueY);
}

template<class COORD1, class COORD2, class... COORDs>
Outcome get_out_from_coords() {
  return cal_out( get_out_from_coords<COORD1, COORD2>(), COORDs::valueX, COORDs::valueY...);
  //manipulating the pack expressions to get something like this                      
}

注意:Outcome不能这样计算Outcome cal_out(Outcome, Outcome) 所以,在这种情况下,像折叠表达式这样的东西是行不通的。即

template<class... COORDs>
Outcome get_out_from_coords() {
  return cal_out(cal_out(COORDs::valueX, COORDs::valueY)...);
}
template<class... COORDs>
Outcome get_out_from_coords() {
  return std::apply(
    [](int x, int y, auto... args){ return cal_out(cal_out(x, y), args...); },
    std::tuple_cat(std::make_tuple(COORDs::valueX, COORDs::valueY)...)
  );
}

这只是连接所有 valueX/valueY 对并使用这些参数调用 cal_out。这里假设一切都是 by-value 并且复制参数很便宜。如果不满足这些条件,则应使用 lambda 中的 std::forward_as_tuple 和 perfect-forwarding。

我也觉得cal_out的定义很奇怪。我认为应该有一个不需要 Outcome 的可变参数重载,然后可以用

调用它
[](auto... args){ return cal_out(args...); }

改为 lambda。否则,如果只有一个 COORDs.

,则需要添加特殊情况