template<class F, class T> using add_member_pointer_t = F T::*;
template<class T> struct remove_member_pointer { using type = T; };
template<class T, class P> struct remove_member_pointer<P T::*> { using type = P; };
template<class T> using remove_member_pointer_t = typename remove_member_pointer<T>::type;
struct C {
void f(int, int) const;
void g(int);
};
static_assert(std::is_same_v<add_member_pointer_t<void(int, int) const, C>, decltype(&C::f)>);
static_assert(std::is_same_v<add_member_pointer_t<void(int), C>, decltype(&C::g)>);
static_assert(std::is_same_v<void(int, int) const, remove_member_pointer_t<decltype(&C::f)>>);
static_assert(std::is_same_v<void(int), remove_member_pointer_t<decltype(&C::g)>>);