template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
using type=T;
};
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
- это класс функции-члена F
.
Для обработки const / volatile / и т.д. вам в конечном итоге придется сделать кучу версий.Это раздражает.Вот пример этого:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...) \
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T; \
}
возможно, вы хотите:
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T __VA_ARGS__; \
}
- это тип класса указателя на const memfun или const класса?
После того, как вы выбрали, вам нужно написать 24 использованных выше макроса:
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
Я не знаю, как избежать выполнения всех 24 из этих специализаций для полного охвата.Если вы думаете, что это глупо, вы правы;Пожалуйста, не стесняйтесь выражать свое раздражение, предлагая исправление стандартному комитету C ++.
Если вы делаете что-то подобное для более чем одной черты, вы можете написать «квалификаторы strip lvalue, rvalue, noexcept и cv"от части в одном месте и раздать их по частям.
Живой пример .