I think code will better illustrate my need:
template <typename F>
struct return_type
{
typedef ??? type;
};
so that:
return_type<int(*)()>::type -> int
return_type<void(*)(int,int)>::type -> void
I know of decltype
and result_of
but they need to have arguments passed. I want to deduce the return type of a function pointer from a single template parameter. I cannot add the return type as a parameter, because that's exactly what I want to hide here...
I know there's a solution in boost, but I can't use it, and an attempt to dig it out from boost resulted in a spectacular failure (as it often does).
C++11 solutions welcome (as long as supported in VS2012).
If you can use variadic templates (November '12 CTP), this should work:
template <class F>
struct return_type;
template <class R, class... A>
struct return_type<R (*)(A...)>
{
typedef R type;
};
If you can't use variadic templates, you'll have to provide specific specialisations for 0, 1, 2, ... parameters (by hand or preprocessor-generated).
EDIT
As pointed out in the comments, if you want to work with variadic functions as well, you'll have to add one extra partial specialisation (or one for each parameter count in the no-variadic-templates case):
template <class R, class... A>
struct return_type<R (*)(A..., ...)>
{
typedef R type;
};
It has been a while since the question has been asked. For C++17, there is an interesting option. However, the syntax is a bit different from what was originally asked, but the result (a type) is the same.
First, we need a helper function. As you see here, the function accepts a function pointer and returns an object of type R. We need this only for a decltype statement and therefore this function will never be called, so a forward declaration is sufficient.
template<typename R, typename... ARGS>
static R return_type(R (*)(ARGS...)); // forward declaration only for decltype
The trick is to provide the function pointer as a template auto parameter, which is forwarded to a decltype statement:
template<auto FUNCTION_POINTER>
using ReturnType = decltype(return_type(FUNCTION_POINTER));
Now it is easy to get the return type:
#include <iostream>
#include <type_traits>
template<typename R, typename... ARGS>
static R return_type(R (*)(ARGS...)); // forward declaration only for decltype
template<auto FUNCTION_POINTER>
using ReturnType = decltype(return_type(FUNCTION_POINTER));
int func1(char c, int i, long l); // also here only forward declarations needed
void func2(unsigned u, float f);
double func3(bool b);
int main()
{
std::cout << std::is_same_v<int, ReturnType<func1>> << std::endl;
std::cout << std::is_same_v<void, ReturnType<func2>> << std::endl;
std::cout << std::is_same_v<double, ReturnType<func3>> << std::endl;
std::cout << std::is_same_v<void, ReturnType<func1>> << std::endl;
}
You can try the complete example in Wandbox: https://wandbox.org/permlink/5akL0MQDoDuJlQNY
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.