Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call each tuple member with a result of the previous call recursively

Lets say I have a tuple std::tuple<Operation<1>, Operation<2>, Operation<3>>. Operation<> has a member function with the signature SomeType someFunction(SomeType). What I want to do is to call the operations successively such that the resulting order of calls would be Operation<3>::someFunction(Operation<2>::someFunction(Operation<1>::someFunction())) and I would get the final SomeType value. How do I achieve this using variadic templates (I have access to C++17)?

I can call each member function with std::apply([](auto& ...x) { (..., x.someFunction()); }, tuple); but what kind of expression do I need to call someFunction() with the output of the previous call?

like image 677
Dago Avatar asked Mar 20 '19 07:03

Dago


1 Answers

I suppose you can combine std::apply() and template folding with a lambda as follows

   auto l = [&val](auto ... Ops) 
    { ((val = Ops.someFunc(val)), ...); };

The following is a full working example

#include <tuple>
#include <iostream>

template <int I>
struct Oper
 {
   static constexpr int someFunc (int i)
    { return i + I; }
 };

int main ()
 {
   std::tuple<Oper<1>, Oper<2>, Oper<3>, Oper<4>>  t;

   int val {}; // starting value

   auto l = [&val](auto ... Ops) 
    { ((val = Ops.someFunc(val)), ...); };

   std::apply(l, t);

   std::cout << val << std::endl;
 }
like image 129
max66 Avatar answered Sep 30 '22 01:09

max66