Alex Blog

[Lambda] Lambda介绍,hailort async API中具体使用说明以及python中扩展应用

Lambda简介

C++中的Lambda表达式(也称为lambda函数或匿名函数)是一种简洁方便的方式来定义匿名函数。它们在C++11中引入,并已成为编写简洁易读代码的流行功能。

Lambda表达式的结构通常由三个部分组成:

  1. 捕获子句(可选):

    • 捕获子句用于指定lambda表达式可以访问的外部变量。
    • 语法:[capture-list]
    • 捕获模式:
      • [=]:按值捕获所有外部变量
      • [&]:按引用捕获所有外部变量
      • 混合捕获:同时按值和按引用捕获部分外部变量
  2. 参数列表(可选):

    • 参数列表用于定义lambda表达式接收的参数。
    • 语法:(parameter1, parameter2, ...)
    • 参数类型的自动类型推导
  3. 函数体:

    • 函数体用于指定lambda表达式执行的代码。
    • 语法:{ ... }
    • 可以使用return关键字返回值

Lambda表达式的优点:

  • **简洁性:**Lambda表达式可以将函数定义嵌入到代码中,使代码更加简洁易读。
  • **可读性:**Lambda表达式将函数定义与函数使用紧密结合,提高了代码的可读性。
  • **灵活性:**Lambda表达式可以捕获外部变量,使其适用于各种场景。

Lambda表达式的用途及其范例:

  1. 回调函数:

    Lambda表达式经常用于作为回调函数传递给其他函数或库。例如:

    C++
    // 使用lambda表达式作为std::for_each算法的回调函数
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(numbers.begin(), numbers.end(), [](int n) {
        std::cout << n << " ";
    });
    

    输出:

    1 2 3 4 5
    
  2. 排序和筛选:

    Lambda表达式可以用于定义排序和筛选数据的比较标准。例如:

    C++
    // 使用lambda表达式对std::vector进行排序
    std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
    std::sort(names.begin(), names.end(), [](const std::string& a, const std::string& b) {
        return a.size() < b.size();
    });
    

    输出:

    Alice Bob Charlie
    

    该代码将names向量中的元素按字符串长度从小到大排序。

  3. 算法实现:

    Lambda表达式可以用于在循环或数据处理管道中实现自定义算法或逻辑。例如:

    C++
    // 使用lambda表达式计算向量中元素的平方和
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int sum_of_squares = std::accumulate(numbers.begin(), numbers.end(), 0, [](int sum, int n) {
        return sum + n * n;
    });
    

    sum_of_squares变量的值为50。

注意事项

  • Lambda表达式不适用于定义需要全局状态修改或扩展代码块的函数。
  • Lambda表达式可以与模板一起使用来创建泛型lambda函数。
  • 标准库算法(例如std::sortstd::find_if)接受lambda表达式作为参数。

总结

Lambda表达式是C++中一种强大的工具,可以用于简化代码、提高可读性和实现各种功能。理解Lambda表达式的结构、优点、用途及其注意事项,可以帮助你更好地利用它们来编写更简洁、更易读、更高效的C++代码。

以上内容是我用Gemini生成的,请知悉。熟悉了基本的Lambda的使用方式后,再来查看hailort async API中具体范例的部分。

hailort async example

hailort的example:async_infer_advanced_example.cpp 中,我们可以注意到它回调函数的使用方式:

auto job = configured_infer_model->run_async(bindings.value(), [] (const AsyncInferCompletionInfo &/*completion_info*/) {
// Use completion_info to get the job status and the corresponding bindings
});

这里我们可以看到他就是使用Lambda表达式作为回调函数,这样做的一个好处是,我们可以在{}内使用本身函数里面的一些变量,可以超越本身回调函数的参数限制(待验证)

那么在python中,我们有类似的方式实现类似的功能么?

pyhailort async example

如果在python的class里面的话,我们可以尝试在初始化的时候就在init函数中定义好对应的callback函数

class HailoExecutor():
    def __init__(self, model):
        self.job_queue = Queue()
        def hailo_infer_callback(error_code):
            AsyncInferJob.validate_job_status(error_code)
            c_job = self.job_queue.get()
            self.results.append(copy.deepcopy(c_job.result))
        self.callback = hailo_infer_callback

这样就可以在调用run_async的时候以这个callback作为回调函数

cur_job = self.configured_infer_model.run_async([self.bindings], self.callback)

你可以注意到,回调函数里面使用了额外的参数self.job_queue, 其实你可以增加更多你需要使用的参数。

另外一种情形则是在其他本身定义好的函数中,需要给回调函数额外增加参数。
我们只需要在本身函数里面定义一个函数即可

def main(hef_path,num_of_frames,job_queue,):
    def example_callback(error_code):
        AsyncInferJob.validate_job_status(error_code)
        c_job = job_queue.get()
        #other code
    ......
    last_job = configured_infer_model.run_async([bindings], example_callback, )

这样其实也是一种迂回的方式实现

 


已发布

分类

, ,

来自

标签:

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注