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.
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.
decltype
would work for this, along with changing foo
's return type to auto
.
template<typename Func, typename T_in>
auto foo( Func f, const std::vector<T_in>& input)
{
std::vector<decltype(f(input[0]))> 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;
}
Using a map of functions it actually very common design pattern is c++. i recommend you using std::Map container for this. here is a link.
good luck :)