Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

most elegant variadic functor

Suppose we have two sorts of classes

  • an input class Input
    • defines a type result_type
    • defines set(result_type)
  • an output class Output
    • defines a type result_type
    • defines result_type get() const
    • has a number of Input classes as member variables, on which its output depends

Given an output class and several input classes (arbitrary number), consider the following procedure:

  • loop over each input class and call set() with an appropriate value (defined beforehand)
  • call the get() on the ouput class and collect the result.

This procedure can be seen as a call to a function taking the input's values as arguments an returning the output value.

Write the functor that constructs such a variadic function in the general case.

Constraints are: C++ (most likely C++11), arbitrary number of input classes of possibly different Input::result_types. Note that Input::result_type is not necessarily related to Output::result_type. Aim should first be efficiency, but there's a big bonus if the code is elegant and readable.

Details: For those who wonder how Output is related to Input, one could imagine that Input has a result_type get() const method as well, which returns whatever you provided via set(). Output then has a constructor that takes various Inputs, and stores them (or their reference) as member variables. Output::get() then does some math by using the return values of its input's get() methods, and returns some result of type Output::result_type.

like image 854
yannick Avatar asked Nov 01 '22 07:11

yannick


1 Answers

Here's my solution, others welcome

#include <functional>

template <class Output, class... Inputs>
std::function<typename Output::result_type(typename Inputs::result_type...)>
make_function(const Output& output, Inputs&... inputs) {
  return[&](typename Inputs::result_type... input_vals) {
    int dummy[]{0, (inputs.set(input_vals),0)...};
    return output.get();
  };
}

the int dummy[] line is due to @ecatmur (https://stackoverflow.com/a/12515637/958110)

like image 83
yannick Avatar answered Nov 15 '22 04:11

yannick