Признаки функции-члена
-
21-12-2019 - |
Вопрос
Я пишу класс шаблона, который обтекает функции-члены, чтобы уменьшить некоторые вызовы - если какое-то условие истинно, функцию-член вызывать не нужно.Подпись выглядела бы примерно так
template <typename MemFuncType, MemFuncType> class MemberWrapper;
И я могу специализировать его таким образом:
template <typename R, typename T, R T::* MemFunc> class MemberWrapper<R T::*, MemFunc>{};
Я также хотел бы ограничить количество аргументов R T::*
.Как мне это сделать?
Единственное решение, о котором я могу думать, - это реализовать класс функций-членов traits, предоставляя частичные специализации на основе типа возвращаемого значения, типа функции, списка аргументов и cv-квалификаторов.Это привело бы к громоздкой реализации, подобной текущей std::mem_fn
перегрузки.Есть ли способ сделать это лучше?
РЕДАКТИРОВАТЬ :Измененный Ret
к R
.Как указывалось в комментариях, на самом деле это не тип возвращаемого значения, и специализация была недопустимой.
Решение 2
Типы функций наддува обеспечивает отличную коллекцию функциональных характеристик.Кроме того, это ИТАК, опубликуйте показывает примеры.
Другие советы
Не пытайтесь свести все к одному классу.Функция-член - это функция, которая является членом класса.Следовательно, начните с создания некоторого класса функциональных признаков, например
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... ) > {};
Таким образом, вы можете легко ограничить количество аргументов в вашем классе:
template <typename Ret, typename T>
class MemberWrapper<Ret T::*>
{
static_assert( function_traits<Ret>::arity <= 4,
"More than 4 arguments are not allowed" );
};