A way to check if a member function/free function can be invoked on an object would be to:
#include <type_traits>
#include <utility>
template <class T, class = void>
struct HasMember : std::false_type {};
template <class T>
struct HasMember<T, std::void_t<decltype(std::declval<T>().Foo())>> : std::true_type {};
template <class T, class = void>
struct HasFreeFoo : std::false_type {};
template <class T>
struct HasFreeFoo<T, std::void_t<decltype(Foo(std::declval<T>()))>> : std::true_type {};
struct A { void Foo() {} };
struct B : A {};
struct C : B {};
void Foo(const A &) {}
int main() {
static_assert(HasMember<C>::value, "");
static_assert(HasFreeFoo<C>::value, "");
}
But as what the example demonstrates,
Cis considered to have the memberFoosinceAhas implementedFoo,Cis considered to have the free functionFooimplemented sinceFooacceptconst A &.
What I want to achieve is to have HasMember<A>::value == true && HasMember<C>::value == false. HasFreeFoo<A>::value == true && HasFreeFoo<C>::value == false. Any help is welcome, thanks.
Background: I am implementing a ser/des tool, user can choose to either implement a member function or a free function to specify how should a type get ser/des. And I need to check if such member function / free function are implemented (not inherited from its base) exactly for the given type .