实现C++std::function可调用对象模板

#include<type_traits>
#include <utility>
#include<exception>
#include<iostream>

template<typename T>
class IsEqualityComparable
{
private:
	// test convertibility of == and ! == to bool:
	static void* conv(bool); // to check convertibility to bool

	template<typename U>
	static std::true_type test(decltype(conv(std::declval<U const&>() == std::declval<U const&>())), decltype(conv(!(std::declval<U const&>() == std::declval<U const&>()))));
	// fallback:
	template<typename U>
	static std::false_type test(...);
public:
	static constexpr bool value = decltype(test<T>(nullptr, nullptr))::value;
};

template<typename T, bool EqComparable = IsEqualityComparable<T>::value>
struct TryEquals
{
	static bool equals(T const& x1, T const& x2) {
		return x1 == x2;
	}
};
class NotEqualityComparable : public std::exception
{ };
template<typename T>
struct TryEquals<T, false>
{
	static bool equals(T const& x1, T const& x2) {
		throw NotEqualityComparable();
	}
};

template<typename R, typename... Args>
class FunctorBridge
{
public:
	virtual ~FunctorBridge() {
}
virtual FunctorBridge* clone() const = 0;
virtual R invoke(Args... args) const = 0;
virtual bool equals(FunctorBridge const* fb) const = 0;
virtual bool equalsEx(FunctorBridge const* fb) const = 0;
};
//模板桥接static多态与dynamic多态:就是继承接口并重写实现接口;实现接口时通过对某一模板参数的约束确定统一要求
//【static多态就反映在只要这个模板参数满足约束,就可以是任意类型;dynamic多态反映在接口的继承,和重写实现】
template<typename Functor, typename R, typename... Args>
class SpecificFunctorBridge : public FunctorBridge<R, Args...> {//此处也是模板上的一种外观模式运用,FunctorBridge<R, Args...>提供外观接口;对于任意类型的Functor的实例化,必须满足相关约束
	Functor functor;//这里是桥接 static多态和dynamic多态的精髓;从SpecificFunctorBridge继承FunctorBridge满足相同的外观接口 对于任意的Functor类型只要满足相同约束都可以使用【类型消除】,相当于静态多态的效果;并通过继承接口并实现接口,这是动态多态的反应;
public:
	template<typename FunctorFwd>
	SpecificFunctorBridge(FunctorFwd&& functor)//隐式依赖转换构造推导类型FunctorFwd可以隐式转换到模板类型 Functor
		: functor(std::forward<FunctorFwd>(functor)) {
	} 
	virtual SpecificFunctorBridge* clone() const override {
		return new SpecificFunctorBridge(functor);//满足上述隐式依赖
	}
	
	virtual R invoke(Args... args) const override {//调用底层可调用对象
		return functor(args...);
	}
	virtual bool equals(FunctorBridge<R, Args...> const* fb) const override
	{
		if (auto specFb = dynamic_cast<SpecificFunctorBridge const*> (fb))
		{
			return functor == specFb->functor;
		}
			//functors with different types are never equal:
			return false;
	}

	virtual bool equalsEx(FunctorBridge<R, Args...> const* fb) const 
	{
		if (auto specFb = dynamic_cast<SpecificFunctorBridge const*>(fb)) {
			return TryEquals<Functor>::equals(functor, specFb->functor);
		} 
		//functors with different types are never equal :
		return false;
	}
};

template<typename Signature>
class FunctionPtr;

template<typename R, typename... Args>
class FunctionPtr<R(Args...)>
{
private:
	FunctorBridge<R, Args...>* bridge;//模板上实现(运用)bridge模式 接口与实现分离
public:
	// constructors:
	FunctionPtr() : bridge(nullptr) {
	} 

	//深拷贝动作
	FunctionPtr(FunctionPtr const& other)
		: bridge(nullptr)
	{
		if (other.bridge) {
			bridge = other.bridge->clone();
		}
	}
	
	FunctionPtr(FunctionPtr& other): FunctionPtr(static_cast<FunctionPtr const&>(other)) {
	}

	FunctionPtr(FunctionPtr&& other) : bridge(other.bridge) {
		other.bridge = nullptr;
	}
	//construction from arbitrary function objects :

	template<typename F>
	FunctionPtr(F&& f): bridge(nullptr)//接收任意可调用对象
	{
		using Functor = std::decay_t<F>;
		using Bridge = SpecificFunctorBridge<Functor, R, Args...>;
		bridge = new Bridge(std::forward<F>(f));//此处也基本满足SpecificFunctorBridge转换构造器的隐式依赖
		
	}

	// assignment operators:
	FunctionPtr& operator=(FunctionPtr const& other) {
		FunctionPtr tmp(other);
		swap(*this, tmp);
		return *this;
	} 
	FunctionPtr& operator=(FunctionPtr&& other) {
			delete bridge;
		bridge = other.bridge;
		other.bridge = nullptr;
		return *this;
	} 
	//construction and assignment from arbitrary function objects :
	template<typename F> 
	FunctionPtr & operator=(F && f) {
		FunctionPtr tmp(std::forward<F>(f));
		swap(*this, tmp);
		return *this;
	} 
	// destructor:
	~FunctionPtr() {
		delete bridge;
	}
	friend void swap(FunctionPtr& fp1, FunctionPtr& fp2) {
		std::swap(fp1.bridge, fp2.bridge);
	} 
	explicit operator bool() const {
		return bridge == nullptr;
	} 
	// invocation:
	template<typename... UArgs>
	R operator()(UArgs&&... args) const
	{
		if (bridge)
			return bridge->invoke(std::forward<UArgs>(args)...);
	}

	friend bool operator==(FunctionPtr const& f1, FunctionPtr const& f2) {
		if (!f1 || !f2) {
			return !f1 && !f2;
		} 
		return f1.bridge->equals(f2.bridge);
	}
	friend bool operator!=(FunctionPtr const& f1, FunctionPtr const& f2) {
		return !(f1 == f2);
	}
};




class weight
{
public:
	explicit operator bool() const {
		return true;
	}
	friend bool operator ==(const weight&, const weight&)
	{
		return true;
	}
	void operator()(int n) const
	{
		std::cout << "weight" << std::endl;
	}
};
void Print(int n)
{
	std::cout << "Print" << std::endl;
}
int main()
{
	weight a;
	if (a)//显式的向 bool 的转换可以被隐式的使用,比如控制语句(if, while, for 以及do) 的布尔型条件, 内置的! ,&& 以及 || 运算符, 还有三元运算符 ? : 。 在这些情况下, 该值被认为是“语境上可以转换成 bool”
	{
		&a;
	}

	FunctionPtr<void(int)> ff = Print;
	ff(3);
	FunctionPtr<void(int)> fo = a;
	fo(3);
	FunctionPtr<void(int)> fl = [](int n)->void {std::cout << "lambda" << std::endl; };
	fl(3);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值