I am writing a template class that wraps around member functions to reduce some calls - if some condition is true, the member function doesn't need to be called. The signature would look something like this
template <typename MemFuncType, MemFuncType> class MemberWrapper;
And I can specialize it thus:
template <typename R, typename T, R T::* MemFunc> class MemberWrapper<R T::*, MemFunc>{};
I would also like to restrict the number of arguments of R T::*
. How do I do this?
The only solution I can think of is to implement a member functions traits class by providing partial specializations based on return type, function type, arguments list and cv-qualifiers. This would lead to a cumbersome implementation like the current std::mem_fn
overloads. Is there a way of doing it better?
EDIT : Changed Ret
to R
. As pointed out in the comments, it isn't really the return type and the specialization was invalid.
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
Member functions are operators and functions that are declared as members of a class. Member functions do not include operators and functions declared with the friend specifier. These are called friends of a class. You can declare a member function as static ; this is called a static member function.
The signature of a member function is defined in 1.3. 20 as <class member function> name, parameter type list (8.3. 5), class of which the function is a member, cvqualifiers (if any), and ref-qualifier (if any). Note the signature includes the name.
The main aim of using the member function is to provide modularity to a program, which is generally used to improve code reusability and to make code maintainable.
Don't try putting everything into one class. A member function is a function which is a member of a class. Hence start by creating some function traits class, e.g.
template< typename T >
class function_traits
{
static_assert( sizeof( T ) == 0,
"function_traits<T>: T is not a function type" );
};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) >
{
constexpr static const std::size_t arity = sizeof...( Ts );
using result_type = R;
};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const > : function_traits< R( Ts... ) > {};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) & > : function_traits< R( Ts... ) > {};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const & > : function_traits< R( Ts... ) > {};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) && > : function_traits< R( Ts... ) > {};
template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const && > : function_traits< R( Ts... ) > {};
With that, you can easily limit the number of arguments in your class:
template <typename Ret, typename T>
class MemberWrapper<Ret T::*>
{
static_assert( function_traits<Ret>::arity <= 4,
"More than 4 arguments are not allowed" );
};
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With