Reputation: 4016
I have a function with a templated parameter which accepts another function. Within that function, I'd like to call a different template function which needs to be instantiated with the return-type of function argument.
Since I probably screwed that last paragraph up, let me attempt to clarify with an example:
template <typename funT>
void foo(funT function_to_call)
{
auto data = bar<funT::return_value>();
/// do some stuff with data.
/// call function_to_call, but bar needed to be called first.
}
How do get funT::return_value ?
Many thanks,
Upvotes: 3
Views: 136
Reputation: 3082
Apart from using result_of
as others have suggested, you can also use decltype
.
For the case where function_to_call
accepts no parameters, you can do the following:
auto data = bar<decltype(function_to_call())>();
However, for a more generic case, as @101010 has pointed out, you can have your function accept any number of arguments. The resulting code would look like this:
template <typename funT, typename ...Args>
void foo(funT function_to_call, Args&&... args)
{
auto data = bar<decltype(function_to_call(std::forward<Args>(args)...))>();
}
For the cases that I've tried, decltype
and std::result_of
have the same functionality with regards to returning the correct type if the function type being passed in isn't a pointer-to-member, as @hvd pointed out. Looking looking through the g++ source, std::result_of
is often implemented in terms of decltype
for the case described above.
Using this seems much cleaner and more readable to me than the typename std::result_of<...>::type
alternative, although the C++14 std::result_of_t
option is quite attractive as well.
Upvotes: 1
Reputation: 42889
You could use type traits in particular std::result_of
in the following manner:
template <typename funT>
void foo(funT function_to_call) {
auto data = bar<typename std::result_of<decltype(function_to_call)&()>::type>();
//...
}
You could also further generalize to accept any kind of function along with its input arguments by using variadic templates in the following manner:
template <typename funT, typename ...Args>
void foo(funT function_to_call, Args... args) {
auto data = bar<typename std::result_of<funT(Args...)>::type>();
...
}
Upvotes: 1
Reputation: 3172
You can use typename std::result_of<funT()>::type
to fit your needs, or std::result_of_t<funT()>
if you have access to C++14.
Upvotes: 0