问题
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.
回答1:
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
回答2:
Boost Function Types provides a great collection of function traits. Also, this SO post shows examples.
来源:https://stackoverflow.com/questions/25044869/member-function-traits