参考
https://zhuanlan.zhihu.com/p/362173165
#include <iostream>
#include <functional>
template<typename F, typename... ARGS>
auto myInvoke(F&& funObj, ARGS&&... args) -> decltype(std::forward<F>(funObj)(std::forward<ARGS>(args)...))
{
return std::forward<F>(funObj)(std::forward<ARGS>(args)...);
}
namespace impl {
template<bool checkif, typename T = void>
struct enable_if {};
template<typename T>
struct enable_if<true,T> {
using type = T;
};
template<bool checkif, typename T = void>
using enable_if_t = typename enable_if<checkif, T>::type;
template<typename B,typename D>
struct IsDClassFromBClass {
using B_D_T = std::decay_t<B>;
using D_D_T = std::decay_t<D>;
static auto check(B_D_T*) -> int;
static auto check(...) -> void;
static constexpr bool value = !std::is_void_v<decltype(check((D_D_T*)0))>;
};
template<typename B, typename D>
constexpr bool IsDClassFromBClass_v = IsDClassFromBClass<B, D>::value;
template<typename B,typename D, enable_if_t<IsDClassFromBClass_v<B,D>, std::decay_t<D>>* = nullptr >
auto getRightObj(D&& obj) ->decltype(static_cast<D&&>(obj)) {
return static_cast<D&&>(obj);
}
template<typename B, typename D, enable_if_t<!IsDClassFromBClass_v<B,D>, std::decay_t<D>>* = nullptr >
auto getRightObj(D&& obj) ->decltype(*(static_cast<D&&>(obj))) {
return *(static_cast<D&&>(obj));
}
}
template<typename R,typename T,typename C,typename ...Args>
auto myInvoke(R(T::* mfun)(Args...), C&& obj, Args&&... args) -> decltype((impl::getRightObj<T>(std::forward<C>(obj)).*mfun)(std::forward<Args>(args)...)) {
return (impl::getRightObj<T>(std::forward<C>(obj)).*mfun)(std::forward<Args>(args)...);
}
template<typename R, typename T, typename C, typename ...Args>
auto myInvoke(R(T::* mfun)(Args...) const, C&& obj, Args&&... args) -> decltype((impl::getRightObj<T>(std::forward<C>(obj)).*mfun)(std::forward<Args>(args)...)) {
return (impl::getRightObj<T>(std::forward<C>(obj)).*mfun)(std::forward<Args>(args)...);
}
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
int test() {
std::cout << "test" << std::endl;
return 1;
}
class Base {
public:
virtual int run(int) {
return 1;
}
};
class Tester:public Base {
public:
virtual int run(int) override{
return 2;
}
float test(int a) const{
std::cout << "Tester::test" << std::endl;
return 9.1f;
}
static void stest(int ) {}
};
int main(int argc,char** argv) {
Tester a;
//函数指针,lamba,类静态成员函数
myInvoke(test);
myInvoke([]() {});
myInvoke(&Tester::stest,5);
//类非静态成员函数
myInvoke(&Tester::test, a,3);
//解决const
const Tester b;
myInvoke(&Tester::test, b,1);
//解决指针
Tester* c = &a;
myInvoke(&Tester::test, c, 1);
//访问基类函数
Tester* d = new Tester();
myInvoke(&Tester::run, d, 11);
return 0;
}