Reputation: 6616
Is it possible to write a template to extract the return type and argument types of the function pointer type to which a class is convertible to, knowing only the class itself? Example:
struct Foo {
using FnPtr = int (*)(char, double);
operator FnPtr() const { ... }
};
// Can I extract the return type (int) and argument types (char and double),
// knowing only `Foo` as an opaque type?
Upvotes: 2
Views: 174
Reputation: 65620
If Foo
doesn't have any other conversion operators and doesn't define an indirection operator, then you can rely on the fact that *a_foo
will give a reference to a function of the desired type. From that, you just need to extract the return and arguments.
func_ref_traits
here will do the extraction:
template <typename Func>
struct func_ref_traits;
template <typename Ret, typename... Args>
struct func_ref_traits<Ret(&)(Args...)> {
using ret = Ret;
using args = std::tuple<Args...>;
};
Then conv_func_traits
will work out the function type from the given type:
template <typename T>
using conv_func_traits = func_ref_traits<decltype(*std::declval<T>())>;
You would use this like so:
conv_func_traits<Foo>::args //std::tuple<char,double>
conv_func_traits<Foo>::ret //int
Upvotes: 6
Reputation: 3460
Here you go:
#include <type_traits>
template <typename...> struct typelist;
template <typename> struct Extract;
template <typename R, typename ...Args>
struct Extract<R(*)(Args...)>
{
using Result = R;
using Arguments = typelist<Args...>;
};
template <typename T>
using Return_Type = typename Extract<typename T::FnPtr>::Result;
template <typename T>
using Arguments = typename Extract<typename T::FnPtr>::Arguments;
struct Foo
{
using FnPtr = int (*)(char, double);
};
int main()
{
static_assert(std::is_same<Return_Type<Foo>, int>::value, ":(");
static_assert(std::is_same<Arguments<Foo>, typelist<char, double>>::value, ":(");
}
I used a typelist to represent the arguments, you could use std::tuple
if you like that better. Additionally, you may need more specializations of Extract
to cover different kinds of callable things.
Upvotes: 3