I have a member variable of a class, offsets
, which is a vector with at leastN 1
elements. I would like to create a member function which will return a tuple with N
entries with values of successive elements of the vector divided by each other. An example is shown below for a specific instance of this function when N=3
.
std::tuple<3> get_shape()
{
return std::make_tuple(offsets[N]/offsets[N-1], offsets[N-1]/offsets[N-2], offsets[N-2]/offsets[N-3]);
}
Is there a way that this sequence can be generalized to implement the function std::tuple<N> get_shape()
?
CodePudding user response:
You can implement this with std::index_sequence
.
template<size_t N>
struct foo {
std::array<double, N 1> offsets;
auto get_tuple() const {
auto make_tuple =
[this]<typename I, I... idx>(std::index_sequence<idx...>) {
return std::make_tuple((offsets[N - idx] / offsets[N - idx - 1])...);
};
return make_tuple(std::make_index_sequence<N>());
}
};
std::make_index_sequence<N>
turns into std::index_sequence<0, 1, 2, ... N - 1>
. This can be applied on a templated lambda since c 20. Where we can access 0, 1, 2, ... N - 1
via the variadic I... idx
. Now saying ...
inside std::make_tuple
will unpack all the idx
numbers into N
arguments
int main() {
foo<3> f = { 2, -4, 7, 1 };
auto tuple = f.get_tuple();
static_assert(std::is_same_v<decltype(tuple), std::tuple<double, double, double>>);
std::apply([](auto&&... rest) {
((std::cout << rest << " "), ...);
}, tuple);
}
output:
0.142857 -1.75 -2