Search code examples
c++c++14callabletemplate-argument-deduction

Get input/output type of callable


I have the following problem:

template<typename Func, typename T_in = /*input type of Func */, typename T_out = /*output type of Func */>
std::vector<T_out> foo( Func f, const std::vector<T_in>& input)
{
  std::vector<T_out> res( input.size() );

  for( size_t i = 0 ; i < input.size() ; ++i )
    res[ i ] = f( input[ i ] );

  return res;
}


int main()
{
  // example for f(x) = x*x
  std::vector<float> input = { /* ... */ };
  auto res = foo( [](float in){ return in*in; }, input );

  return 0;
}

As you can see above, I try to implement a function foo which maps a function f to each element of an input vector input. My problem is the following: I want the elements of the input vector input to have the input type of f (i.e., T_in) and the elements of the output vector the output type of f (i.e., T_out) but without passing the input/output type of f explicitly to foo (due to a better readability of the code). Has anyone an idea how the input/output type of f can be deduced automatically at compile time?

Many thanks in advance.


Solution

  • The type T_in can be deduced from the input vector.

    I think that the deduction of T_out is a work for std::result_of_t

    template <typename Func, typename T_in,
              typename T_out = std::result_of_t<Func(T_in)>>
    std::vector<T_out> foo( Func f, const std::vector<T_in>& input)
    {
      std::vector<T_out> res( input.size() );
    
      for( size_t i = 0 ; i < input.size() ; ++i )
        res[ i ] = f( input[ i ] );
    
      return res;
    }
    

    Using typename std::result_of<Func(T_in)>::type instead of std::result_of_t<Func(T_in)> should work also for C++11, not only for C++14.