ThreadPool does not work with lambdas

ThreadPool::runJob() has two overloads that take std::functions. That’s nice. But unfortunately they don’t work with lambdas:

myThreadPool.addJob([]{
  // do stuff 
  return ThreadPoolJob::jobHasFinished;
});  // error: call to addJob is ambiguous :(

Suggestion: instead of taking a std::function in the interface, make runJob a member function template that takes an argument of any callable type T (perhaps SFINAEd on std::is_invocable_r with the return types you want to allow), and then create a std::function from it under the hood as an implementation detail. This way you’ll also need only one overload instead of two (fixing that error above). It shouldn’t even break any client code.

1 Like

Interesting idea for sure. But I should mention that the std::is_invocable series are only C++17 compatible, which might break VS2013 support.

I use lambdas for addJob all the time. They work just fine.

addJob doesn’t work (that is, doesn’t even compile) if you want to use the version that returns the job status. (At least on Visual Studio, it doesn’t even help if you explicitly set the return type for the lambda.)

Maybe @timur should edit his post then? He mentions both overloads and then directly follows up with “they don’t work with lambdas”. Well, one of the two works just fine with lambdas.

Please no SFINAE / type_traits. In my opinion it’s good that JUCE is very modest with those C++ features that blow up compile times (source).

I’ve done a lot of compile-time profiling with Templight and have found that metaprogramming is especially expensive on Lambdas, because each is its own unique type and causes its own (chain of) template instantiations.