C++中std::function详解和实战示例

一、std::function 是什么?

std::function 是 C++11 引入的通用函数封装器,可以容纳任何“可调用对象”:

  • 普通函数
  • Lambda 表达式(含捕获)
  • 函数指针
  • 成员函数绑定(如 std::bind
  • 可调用类或仿函数(operator()

它是 <functional> 中定义的模板类:

template< class R, class... Args >
class function<R(Args...)>;

意味着 std::function<void(int)> 表示可接收一个 int 参数、无返回值的任何可调用对象。


二、应用场景总结

场景描述
回调机制可存储传入的回调函数(例如事件触发、完成通知)
异步任务调度用作任务队列中的任务封装
策略模式在运行时动态替换策略行为(如算法接口)
通用函数接口支持用户传入任意处理逻辑,提高系统模块化

三、与函数指针的比较

特性函数指针std::function
只支持普通函数
支持 lambda
支持捕获 lambda
支持成员函数(对象)部分(需要绑定)✅(支持 std::bind 或 lambda)
类型安全、泛型
内存开销较小较大,但可忽略(有类型擦除)

四、代码示例

1. 基础用法:封装函数、lambda、函数指针

#include <iostream>
#include <functional>

void sayHello() {
    std::cout << "Hello\n";
}

int add(int a, int b) {
    return a + b;
}

int main() {
    std::function<void()> f1 = sayHello;
    f1(); // 输出:Hello

    std::function<int(int, int)> f2 = add;
    std::cout << f2(3, 4) << "\n"; // 输出:7

    std::function<int(int, int)> f3 = [](int x, int y) {
        return x * y;
    };
    std::cout << f3(2, 5) << "\n"; // 输出:10
}

2. 成员函数与绑定

#include <iostream>
#include <functional>

class Worker {
public:
    void process(int x) {
        std::cout << "Processing: " << x << "\n";
    }
};

int main() {
    Worker w;
    // 绑定成员函数
    std::function<void(int)> cb = std::bind(&Worker::process, &w, std::placeholders::_1);
    cb(42); // 输出:Processing: 42
}

3. 捕获 lambda 作为回调

#include <iostream>
#include <functional>

void doSomething(std::function<void(int)> callback) {
    for (int i = 0; i < 3; ++i) {
        callback(i);
    }
}

int main() {
    int count = 0;
    doSomething([&count](int x) {
        count += x;
        std::cout << "Got: " << x << ", total: " << count << "\n";
    });
}

4. 与任务调度系统结合使用(轻量)

#include <iostream>
#include <vector>
#include <functional>

class TaskQueue {
public:
    void addTask(const std::function<void()>& task) {
        tasks_.push_back(task);
    }

    void run() {
        for (auto& task : tasks_) {
            task();
        }
    }

private:
    std::vector<std::function<void()>> tasks_;
};

int main() {
    TaskQueue q;
    q.addTask([]() { std::cout << "Task A\n"; });
    q.addTask([]() { std::cout << "Task B\n"; });

    q.run();  // 输出 Task A 和 Task B
}

5. 回调注册系统(模拟事件中心)

#include <iostream>
#include <functional>
#include <vector>

class EventSystem {
public:
    using Callback = std::function<void(int)>;

    void registerCallback(const Callback& cb) {
        callbacks_.push_back(cb);
    }

    void trigger(int val) {
        for (auto& cb : callbacks_) {
            cb(val);
        }
    }

private:
    std::vector<Callback> callbacks_;
};

int main() {
    EventSystem es;

    es.registerCallback([](int x) { std::cout << "Callback A: " << x << "\n"; });
    es.registerCallback([](int x) { std::cout << "Callback B: " << x * 2 << "\n"; });

    es.trigger(5);
}

五、典型场景应用实战示例

下面是针对三种典型应用场景 —— 异步线程池事件广播系统插件系统接口std::function 应用讲解与完整 C++ 示例代码。这三种结构中,std::function核心桥梁,用于高效、安全地封装任务、回调与动态行为。


1. 异步线程池任务封装

使用 std::function<void()> 封装任意任务并在线程中异步执行。

示例:轻量级线程池结构
#include <iostream>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <atomic>

class ThreadPool {
public:
    using Task = std::function<void()>;

    ThreadPool(size_t threadCount = std::thread::hardware_concurrency()) {
        running = true;
        for (size_t i = 0; i < threadCount; ++i) {
            workers.emplace_back([this]() {
                while (running) {
                    Task task;
                    {
                        std::unique_lock<std::mutex> lock(mutex);
                        cond.wait(lock, [this]() {
                            return !taskQueue.empty() || !running;
                        });
                        if (!running && taskQueue.empty()) return;
                        task = std::move(taskQueue.front());
                        taskQueue.pop();
                    }
                    task();
                }
            });
        }
    }

    ~ThreadPool() {
        running = false;
        cond.notify_all();
        for (auto& t : workers) {
            if (t.joinable()) t.join();
        }
    }

    void enqueue(Task task) {
        {
            std::lock_guard<std::mutex> lock(mutex);
            taskQueue.push(std::move(task));
        }
        cond.notify_one();
    }

private:
    std::vector<std::thread> workers;
    std::queue<Task> taskQueue;
    std::mutex mutex;
    std::condition_variable cond;
    std::atomic<bool> running;
};

// 使用示例
int main() {
    ThreadPool pool(4);
    for (int i = 0; i < 5; ++i) {
        pool.enqueue([i]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            std::cout << "Task " << i << " done\n";
        });
    }
}

2. 事件广播系统(Observer 模式)

std::function 用作回调函数注册,支持多个监听器。

示例:事件中心
#include <iostream>
#include <vector>
#include <functional>

class EventDispatcher {
public:
    using Listener = std::function<void(int)>;

    void addListener(const Listener& listener) {
        listeners.push_back(listener);
    }

    void broadcast(int eventCode) {
        for (auto& listener : listeners) {
            listener(eventCode);
        }
    }

private:
    std::vector<Listener> listeners;
};

// 使用示例
int main() {
    EventDispatcher dispatcher;

    dispatcher.addListener([](int code) {
        std::cout << "Listener A received: " << code << "\n";
    });

    dispatcher.addListener([](int code) {
        std::cout << "Listener B processed: " << code * 2 << "\n";
    });

    dispatcher.broadcast(100);
}

3. 插件系统接口封装

利用 std::function 封装动态传入的“行为实现”(比如一个插件模块提供的处理函数)。

示例:插件行为接口
#include <iostream>
#include <functional>
#include <memory>

class PluginInterface {
public:
    using Callback = std::function<void(const std::string&)>;

    void registerCallback(Callback cb) {
        onMessage = cb;
    }

    void emitMessage(const std::string& msg) {
        if (onMessage) onMessage(msg);
    }

private:
    Callback onMessage;
};

// 模拟插件
class MyPlugin {
public:
    void attachTo(PluginInterface& iface) {
        iface.registerCallback([this](const std::string& msg) {
            std::cout << "[MyPlugin] received: " << msg << "\n";
        });
    }
};

// 使用示例
int main() {
    PluginInterface iface;
    MyPlugin plugin;

    plugin.attachTo(iface);
    iface.emitMessage("Hello from core system!");
}

总结

应用用法std::function 类型
线程池封装任意任务std::function<void()>
事件系统注册/触发事件响应回调std::function<void(Event)>
插件接口动态注册功能实现std::function<void(const std::string&)> 或更复杂结构

六、最佳实践

  • 若性能敏感且固定调用对象,用 函数指针或模板
  • 若需要灵活性、支持绑定 lambda/状态对象,优先使用 std::function
  • 尽量用 const std::function<>& 引用传参,避免拷贝;
  • 如果回调频繁被调用(如每帧),也可以结合 std::move

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云SLAM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值