Hello,

suppose you have following clases:

struct Mock{
static int inc(int){
return 0;
} static int dec(int){
return 0;
}
}; struct Real{
Real(int v) : v(v){} int inc(int a) const{
return a + v;
} int dec(int a) const{
return a - v;
} private:
int v;
}; template<typename C, typename F>
auto user(C &c, F func){
return (c.*func)(5);
}
This will allow to call:

user(real, &Real::inc);

but will not allow to do

user(real, &Mock::inc);

However because of generic context, both calls must be possible.

Here is simple implementation of the feature:

#include <type_traits>

namespace class_invoke_impl_{
    template <class T, class F, class... Args>
    constexpr auto class_invoke_(T &&cl, F func, std::true_type, Args&&... args){
        return (std::forward<T>(cl).*func)(std::forward<Args>(args)...);
    } 
 
    template <class T, class F, class... Args>
    constexpr auto class_invoke_(T const &, F func, std::false_type, Args&&... args){
        return func(std::forward<Args>(args)...);
    }
 
template <class T, class F, class... Args>
constexpr auto class_invoke(T &&cl, F func, Args&&... args){
    using namespace class_invoke_impl_;
    return class_invoke_(std::forward<T>(cl), func, std::is_member_pointer<F>{}, std::forward<Args>(args)...);
}