0

This is template for holding class member method signature. It has no default implementation, but have specialized for every case when method has or has not c-style variadic parameters and has or has not all combinations of cv-qualifiers. And all these things yields 8 very similar pieces of code. Could anyone suggest some method to shrink this template:

#include <type_traits>
template <typename ... args>
struct params_t
{
    // ...
};

template <typename T>
struct mem_fn_t;

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... )>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... );
    typedef typename std::remove_pointer<pfunction>::type function;
};


template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... ) const>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... ) const;
    typedef typename std::remove_pointer<pfunction>::type function;
};

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... ) volatile>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... ) volatile;
    typedef typename std::remove_pointer<pfunction>::type function;
};

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... ) const volatile>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... ) const volatile;
    typedef typename std::remove_pointer<pfunction>::type function;
};

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... , ... )>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... , ... );
    typedef typename std::remove_pointer<pfunction>::type function;
};


template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... , ... ) const>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... , ... ) const;
    typedef typename std::remove_pointer<pfunction>::type function;
};

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... , ... ) volatile>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... , ... ) volatile;
    typedef typename std::remove_pointer<pfunction>::type function;
};

template <typename class_t, typename ret_val_t, typename ... args>
struct mem_fn_t<ret_val_t (class_t::*)(args ... , ... ) const volatile>
{
    typedef class_t class_type;
    typedef ret_val_t result_type;
    typedef params_t<args...> params_type;
    typedef result_type (class_type::*pfunction)(args ... , ... ) const volatile;
    typedef typename std::remove_pointer<pfunction>::type function;
};
user2807083
  • 2,962
  • 4
  • 29
  • 37
  • Does [this](http://stackoverflow.com/questions/14926482/const-and-non-const-template-specialization) help at all? – Matt Mar 28 '16 at 15:39
  • Maybe, but I can't see how. I want to save info about cv inside class, and not wipe it out. – user2807083 Mar 28 '16 at 15:50

1 Answers1

2

Just use plain inheritance.

template<typename C, typename R, typename... Args>
struct base_mem_fn_t {
    using class_type = C;
    using result_type = R;
    using params_type = params_t<Args...>;
};

If every classes you've made inherits this one, you can reduce a lot of lines of code and repetition.

Btw there are a lot of qualifier missing, you should have around 30 overload if you take c-style variadics and rvalue for this into account.

Here's an example from my code, taken from github: http://coliru.stacked-crooked.com/a/03bff2946f1d3097

Original code here: https://github.com/gracicot/kangaru/blob/master/include/kangaru/detail/function_traits.hpp

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141