当前位置: 首页 > news >正文

C++手写std::function

#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

相关文章:

  • Three.js关键帧动画不连续正放、倒放出现的部分问题
  • 【PVR Review】《A Review of Palmar Vein Recognition》
  • atypica.AI:用「语言模型」为「主观世界」建模
  • Redis的哨兵
  • 深度学习基础--CNN经典网络之分组卷积与ResNext网络实验探究(pytorch复现)
  • EasyX 图形库学习笔记
  • c#程序结构
  • 单北斗终端:铸就国产科技脊梁
  • 告别 ifconfig:为什么现代 Linux 系统推荐使用 ip 命令
  • 【蓝桥杯Web】2022年十三届省赛大学组真题 冬奥大抽奖 介绍 蓝桥云课庆冬奥需要举行一次抽奖活动,我们一起做一个页面提供给云课冬奥抽奖活动使用。
  • 【算法】【蓝桥23国A软件C】四版代码思路分析与逐步优化
  • influxdb数据导出笔记
  • 【结肠息肉AI论文集】Shallow Attention Network for Polyp Segmentation
  • Flutter容器组件深度解析
  • C++基础精讲-02
  • idea里面不能运行 node 命令 cmd 里面可以运行咋回事啊
  • 北京大学DeepSeek内部研讨系列:AI在新媒体运营中的应用与挑战|122页PPT下载方法
  • Excel通过VBA脚本去除重复数据行并保存
  • 2025年常见渗透测试面试题- PHP考察(题目+回答)
  • Kotlin 通用请求接口设计:灵活处理多样化参数
  • java网站建设/seo值是什么意思
  • 婚礼请柬电子版免费制作app/武汉网站搜索引擎优化
  • 中国安能建设总公司网站/青岛seo优化
  • 设计衣服的网站/网络推广哪个平台好
  • 烟台教育网站建设/网络营销的市场背景
  • 新疆建设人才培训网/个人如何做seo推广