user2807083
user2807083

Reputation: 2972

How to minimize template code?

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;
};

Upvotes: 0

Views: 213

Answers (1)

Guillaume Racicot
Guillaume Racicot

Reputation: 41770

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

Upvotes: 2

Related Questions