#include <iostream>
#include <memory>
using namespace std;
// 抽象接口类
template <class R, class... Args>
struct ICallable
{
// 定义通用的函数行为,隐藏真实的类型
virtual R invoke(Args &&...args) = 0;
virtual ~ICallable() {};
};
// 包装任意类型桥接类
template <class T, class R, class... Args>
class ICallableImpl : public ICallable<R, Args...>
{
// 封装任意类型的函数指针
T callable;
public:
ICallableImpl(T &&c) : callable(std::move(c)) {};
R invoke(Args &&...args) override
{
return callable(std::forward<Args>(args)...);
}
};
// 函数指针签名
// void(int)封装
// 类似 using ptr = void(int);
template <class Signature>
class MyFunction;
// 具体实现
template <class R, class... Args>
class MyFunction<R(Args...)>
{
// 底层是抽象接口智能指针
std::unique_ptr<ICallable<R, Args...>> funcPtr;
public:
MyFunction() = default;
template <class T>
MyFunction(T &&callable)
{
funcPtr = std::make_unique<ICallableImpl<T, R, Args...>>(std::forward<T>(callable));
}
// 赋值操作符
template <class T>
MyFunction &operator=(T &&callable)
{
funcPtr = std::make_unique<ICallableImpl<T, R, Args...>>(std::forward<T>(callable));
return *this; // 返回 *this 以支持链式赋值
}
// 函数调用
R operator()(Args... args) const
{
// 多态
funcPtr->invoke(std::forward<Args>(args)...);
}
};
void func()
{
std::cout << "hello world\n"
<< endl;
}
int add(int a, int b)
{
return a + b;
}
int main()
{
// R void
// Args... ()
// func class T void() 函数指针
MyFunction<void()> f1(func);
f1();
MyFunction<int(int, int)> f2(add);
// 3
int test = f2(1, 2);
cout << test << endl;
return 0;
}
为什么需要抽象接口类?
因为如果没有抽象接口类,在写定义时 MyFunction<void()> f1(func);
必须还要写出函数指针,如果把此过程写到构造函数中,让编译器自动推导,方便书写。
一定要注意 函数的三个关键, type return,args