5

I'm pretty inexperienced in such things, but I'm trying to create a template function that evaluates a n-variable function at "rotated" argument (see example below) and returns a vector of all these values.

For example for n=3 with a function f(x,y,z) the returned triple\vector should be

< f(x,0,0), f(0,x,0), f(0,0,x) >

The naive version of what I need could look like the following (not necessary correct\working)

typedef FunctionSignature Function;

template<class Function, size_t Dimensions>
std::array<Function::Out,Dimensions> F(Function::InComponent x)
{
  std::array<Function::Out,Dimensions> Result;

  for (i=0; i<Dimensions; i++)    
     Result[i] = Function::f("rotate((x,0,...,0),i)");

  return Result;
}

But how to make the rotate thing.

I also hope that the run-time for could be somehow be eliminated since n is well known in time of compilation.

  • Instead of your `f()` function taking an explicit list of values as parameters, have your `f()` function take a vector of values, instead. Populating the vector with values, to be passed as a parameter, becomes trivial. No need to deal with variadic functions. – Sam Varshavchik Jul 08 '16 at 03:14
  • 1) I have no problem to make 'f' vector valued I guess ...although it could be redundant when 'n'=1. .... 2) "becomes trivial" doesn't help... particularly, I'm not sure how it helps to get it done in compile time. – Michael Medvinsky Jul 08 '16 at 05:07

1 Answers1

5
template<class Function, size_t... Is, size_t... Js>
typename Function::Out call_f(typename Function::InComponent x, 
                              std::index_sequence<Is...>, 
                              std::index_sequence<Js...>) {
    return Function::f((void(Is), 0)..., x, (void(Js), 0)...);
}

template<class Function, size_t Dimensions, size_t... Is>
std::array<typename Function::Out, Dimensions> F(typename Function::InComponent x,
                                                 std::index_sequence<Is...>)
{
  return {{ call_f<Function>(x, std::make_index_sequence<Is>(),
                                std::make_index_sequence<Dimensions - Is - 1>())... }};
}

template<class Function, size_t Dimensions>
std::array<typename Function::Out,Dimensions> F(typename Function::InComponent x)
{
   return F<Function, Dimensions>(x, std::make_index_sequence<Dimensions>());
}

For C++11, search on SO for an implementation of make_index_sequence.

Demo.

T.C.
  • 133,968
  • 17
  • 288
  • 421