`std::function<void()>` 是 C++11 引入的一种通用的函数包装器(functors)

std::function<void()> 是 C++11 引入的一种通用的函数包装器(functors),可以包装任何可调用的对象(如函数指针、lambda 表达式、绑定后的成员函数等)。void Application::Schedule(std::function<void()> callback) 是一个成员函数的声明,表示 Application 类中的 Schedule 方法接受一个可调用对象作为参数。

以下是对这段代码的详细解释:

1. 函数声明

cpp 复制代码
void Application::Schedule(std::function<void()> callback)
  • void:表示该函数没有返回值。
  • Application::Schedule :表示这是 Application 类的成员函数,名为 Schedule。
  • std::function<void()> callback :参数是一个 std::function 对象,类型为 std::function<void()>,表示它是一个不接受参数且没有返回值的可调用对象。

2. std::function<void()> 的作用

std::function<void()> 是一个通用的函数包装器,可以包装以下类型的可调用对象:

  • 普通函数
  • Lambda 表达式
  • 绑定后的成员函数(使用 std::bind)
  • 其他仿函数(functors)

3. 函数的实现

你需要实现这个成员函数。以下是一个可能的实现示例,展示了如何将 callback 添加到一个任务队列中,并可能在一个单独的线程中执行:

cpp 复制代码
#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <mutex>

class Application {
private:
    std::vector<std::function<void()>> task_queue_;
    std::mutex mutex_;
    std::thread worker_;

    void WorkerThread() {
        while (true) {
            std::function<void()> task;
            {
                std::lock_guard<std::mutex> lock(mutex_);
                if (task_queue_.empty()) {
                    continue; // 如果任务队列为空,继续等待
                }
                task = task_queue_.back();
                task_queue_.pop_back();
            }
            task(); // 执行任务
        }
    }

public:
    Application() {
        worker_ = std::thread(&Application::WorkerThread, this);
    }

    ~Application() {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            task_queue_.clear(); // 清空任务队列
        }
        worker_.join(); // 等待工作线程结束
    }

    void Schedule(std::function<void()> callback) {
        std::lock_guard<std::mutex> lock(mutex_);
        task_queue_.push_back(callback);
    }
};

4. 代码解析

  • task_queue_ :一个存储任务的队列,每个任务是一个 std::function<void()>。
  • mutex_ :一个互斥锁,用于保护对 task_queue_ 的访问。
  • WorkerThread:一个工作线程,不断从任务队列中取出任务并执行。
  • Schedule:将任务添加到任务队列中。

5. 使用示例

以下是如何使用 Schedule 函数的示例:

cpp 复制代码
#include <iostream>

void SimpleFunction() {
    std::cout << "Simple function called!" << std::endl;
}

class My class {
public:
    void MemberFunction() {
        std::cout << "Member function called!" << std::endl;
    }
};

int main() {
    Application app;

    // 调度普通函数
    app.Schedule(SimpleFunction);

    // 调度 lambda 表达式
    app.Schedule([]() {
        std::cout << "Lambda expression called!" << std::endl;
    });

    // 调度绑定后的成员函数
    MyClass obj;
    app.Schedule(std::bind(&MyClass::MemberFunction, &obj));

    // 等待一段时间以确保任务被执行
    std::this_thread::sleep_for(std::chrono::seconds(1));

    return 0;
}

6. 注意事项

  • 线程安全 :如果 Schedule 函数可能被多个线程同时调用,需要使用互斥锁(如 std::mutex)来保护对共享资源(如 task_queue_)的访问。
  • 异常处理:如果任务队列中的任务可能抛出异常,需要在工作线程中捕获并处理这些异常。
  • 性能:频繁地调度任务可能会导致性能下降,特别是在任务非常轻量级的情况下。

7. 总结

void Application::Schedule(std::function<void()> callback) 是一个典型的任务调度函数,接受任何可调用对象作为参数,并将其添加到任务队列中。通过使用 std::function,可以灵活地包装各种类型的可调用对象,使得任务调度更加通用和方便。

相关推荐
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
weilx12342 天前
C++笔记-文件IO-<fcntl.h>
c++
Smileyqp沛沛3 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车3 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·3 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁3 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
程序猿编码3 天前
告别改源码适配模型:纯 C++ 可配置 LLM 推理引擎,全格式全结构兼容
c++·大模型·llm·推理引擎
此生决int3 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++