2

The TBB documentation gives this example of using lambda expressions with parallel_for, but doesn't provide an example of using lambda expressions with tbb::task::enqueue.

I am looking for a simple example of tbb::task::enqueue with a lambda expression.

Cosmo Harrigan
  • 895
  • 1
  • 8
  • 22

1 Answers1

7

Low-level tasks in TBB do not directly support lambda expressions. But with some extra coding you might create syntax-sugar helpers to do what you want.

You'd need to create a task class that calls a given functor:

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) {}
};

And then, you'd need to create a function template that takes a functor/lambda, wraps it into lambda_task, and enqueues:

template<typename F>
void tbb_enqueue_lambda( const F& f ) {
    tbb::task::enqueue( *new( tbb::task::allocate_root() ) lambda_task<F>(f) );
}

And then you might use this function with lambda expressions:

tbb_enqueue_lambda( []{ /* code here */ } );

The official TBB API classes that support lambda expressions, such as task_group and task_arena, use very similar code internally.


Update: to pass a function pointer and arguments to call it with, the above approach can be extended in some ways:

Community
  • 1
  • 1
Alexey Kukanov
  • 12,479
  • 2
  • 36
  • 55
  • Improvement suggestions: if lambda returns non-void, use its return value to produce the `tbb::task*` to allow chaining. Maybe split the creation of the `lambda_task` from the `enqueue`? Maybe not. – Yakk - Adam Nevraumont Mar 12 '14 at 16:28
  • Thank you for the helpful answer! How could you modify this to enqueue a pointer to a function that has arguments directly? This works: ```tbb_enqueue_lambda([=]{doTask(arg);});```, as well as ```tbb_enqueue_lambda(&doTask);```, but how could you pass the arguments without the lambda expression? – Cosmo Harrigan Mar 12 '14 at 22:09
  • 1
    I have update the answer to cover passing arguments. – Alexey Kukanov Mar 14 '14 at 18:45
  • Why not to add this to TBB? `task::enqueue()` misses any high-level API – Anton Sep 22 '17 at 17:09