template - 函数

参考

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值