5

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.

yannick
  • 397
  • 3
  • 19

1 Answers1

2

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)

Community
  • 1
  • 1
yannick
  • 397
  • 3
  • 19
  • I'm not shy about admitting I'm utterly lost how the Output class *receives* the input instance(s) for member initialization prior to execution and establishing the final `.get()`. I see the expansion of the inputs in the dummy array, but nowhere are they married to `output`, nor could they be since `output` is `const`. That said, the problem is interesting none-the-less. But note, the request is "Write the functor"; you wrote a *function*. – WhozCraig Jan 17 '14 at 00:19
  • I will add a comment in the question describing this link. For me, a functor is a functional, e.g. a higher-level function, a function that works on function space. I might be wrong. – yannick Jan 17 '14 at 12:33
  • 1
    @yannick: There are other meanings in other domains. In C++, though, a functor is strictly an object that implements `operator()()` so it can quack like a function. – cHao Jan 21 '14 at 19:45