TBB 文档给出了 this example将 lambda 表达式与 parallel_for 结合使用,但未提供将 lambda 表达式与 tbb::task::enqueue
结合使用的示例。
我正在寻找一个带有 lambda 表达式的 tbb::task::enqueue
的简单示例。
最佳答案
TBB 中的低级任务不直接支持 lambda 表达式。但是,通过一些额外的编码,您可以创建语法糖助手来执行您想要的操作。
您需要创建一个调用给定仿函数的任务类:
template<typename F>
class lambda_task : public tbb::task {
F my_func;
/*override*/ tbb::task* execute() {
my_func();
return NULL;
}
public:
lambda_task( const F& f ) : my_func(f) {}
};
然后,您需要创建一个函数模板,它接受一个仿函数/lambda,将其包装到 lambda_task
中,然后入队:
template<typename F>
void tbb_enqueue_lambda( const F& f ) {
tbb::task::enqueue( *new( tbb::task::allocate_root() ) lambda_task<F>(f) );
}
然后您可以将此函数与 lambda 表达式一起使用:
tbb_enqueue_lambda( []{ /* code here */ } );
支持 lambda 表达式的官方 TBB API 类,例如 task_group
和 task_arena
,在内部使用非常相似的代码。
更新:传递一个函数指针和参数来调用它,上面的方法可以在某些方面扩展:
- 在 C++03 中,您需要为具有一个参数、两个参数等的任务添加单独的类模板,以及相应的
tbb_enqueue_lambda
函数重载 - 在 C++11 中,您可以使用可变参数模板,将实际参数存储在
lambda_task
内的std::tuple
中,并为函数“解包”这些参数称呼。解包并不简单,但已经有一些 SO 主题涵盖了这一点:"unpacking" a tuple to call a matching function pointer , How do I expand a tuple into variadic template function's arguments? , 和其他。
关于c++ - 使用 lambda 的线程构建 block (TBB) 排队任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22345935/