#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;
}
实现C++std::function可调用对象模板
最新推荐文章于 2024-04-09 21:24:56 发布