Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type deduction given member function pointer with variadic templates

Assuming I have a member function pointer how I could write code that automatically deduce parameters for given template signature:

 template<typename T> class Foo {};

 template<typename R, typename C, typename... A>
 class Foo<R(C, A...)> { };

For C and R there is no problem as something similar to this does the trick:

template<typename R, typename C, typename... A> 
R deduce_R_type(R(C::*)(A...));

template<typename R, typename C, typename... A>
C deduce_C_type(R(C::*)(A...));

Then I can actually plug it in to the Foo instantiation but how to deduce the types coming from the variadic part of the template?

Foo<
decltype(deduce_R_type(&SomeClass::SomeFunction)) (
decltype(deduce_C_type(&SomeClass::SomeFunction)), ___ ??? ___)> instance
like image 486
Adrian Lis Avatar asked Oct 15 '13 17:10

Adrian Lis


1 Answers

You need at least one helper and something like std::tuple:

template<typename R, typename C, typename... A>
std::tuple<A...> deduce_A_tuple(R(C::*)(A...));

template<typename R, typename C, typename T>
struct FooHelper;

template<typename R, typename C, typename... A>
struct FooHelper< R, C, std::tuple<A...> >
{
    typedef Foo< R( C, A... ) > type;
};

and then you can use:

FooHelper< decltype(deduce_R_type(&SomeClass::SomeFunction)),
           decltype(deduce_C_type(&SomeClass::SomeFunction)), 
           decltype(deduce_A_tuple(&SomeClass::SomeFunction)) >::type instance;

Live example


As user DyP pointed out it could be much simpler when you have to use a helper anyways:

template<typename>
struct FooHelper;

template<typename R, typename C, typename... A>
struct FooHelper< R (C::*)(A...) >
{
    using type = Foo< R( C, A... ) >;
};

and use it as

FooHelper< decltype(&SomeClass::SomeFunction) >::type instance;
like image 123
Daniel Frey Avatar answered Oct 21 '22 11:10

Daniel Frey