1

I have the following problem:

template< typename Func >
class A
{
  public:
    A( Func f ) : _f( f ) {}

    // ...

    template< typename T_in = /*input type of _f */, typename T_out = /*output type of _f */ >
    std::vector<T_out> operator()( 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;
    }

  private:
    Func _f;
    // ...

};

template< typename Func >
A<Func> A_wrapper( Func f )
{
  return A<Func>( f );
}

int main()
{
  // example for f(x) = x*x
  std::vector<float> input = { /* ... */ };

  auto f          = []( float in ){ return in*in; };
  auto map_square = A_wrapper( f );

  auto res = map_square( input );

  return 0;
}

As you can see above, I try to implement a class A whose function operator() 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 the class A, the function A_wrapper which I use for type deduction and/or the function operator() (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.

BTW: The question here is related to my previous post Get input/output type of callable

Community
  • 1
  • 1
abraham_hilbert
  • 2,221
  • 1
  • 13
  • 30
  • [This](http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda) looks like what you want. – NathanOliver Oct 18 '16 at 13:59

1 Answers1

1

Same question, same answer: you can deduce T_in from the input vector and T_out using std::result_of_t

#include <vector>
#include <functional>

template< typename Func >
class A
{
  public:
    A( Func f ) : _f( f ) {}

    // ...

    template< typename T_in,
              typename T_out = std::result_of_t<Func(T_in)>>
    std::vector<T_out> operator()( 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;
    }

  private:
    Func _f;
    // ...

};

template< typename Func >
A<Func> A_wrapper( Func f )
{
  return A<Func>( f );
}

int main()
{
  // example for f(x) = x*x
  std::vector<float> input = { /* ... */ };

  auto f          = []( float in ){ return in*in; };
  auto map_square = A_wrapper( f );

  auto res = map_square( input );

  return 0;
 }

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.

Community
  • 1
  • 1
max66
  • 65,235
  • 10
  • 71
  • 111